zoukankan      html  css  js  c++  java
  • bzoj 3745: [Coci2015]Norma

    Description

    题面

    Solution

    考虑分治:
    我们要统计跨越 (mid) 的区间的贡献
    分最大值和最小值所在位置进行讨论:

    设左边枚举到了 (i),左边 ([i,mid]) 的最大值为 (mx),最小值为 (mn)
    1.最大值最小值都在左边:(sum_{j=mid+1}^{p}mx*mn*(j-i+1)),可以用等差数列直接算出
    2.最大/小值有一个在左边 (sum_{j=p}^{q}mx*Mx[j]*(j-i+1)) 我们可以拆成 (sum_{j=p}^{q}mx*Mx[j]*j-sum_{j=1}^{q}mx*Mx[j]*(i-1))
    3.最大值最小值都在右边:同理,拆除 (j)(i-1) 这两项
    分别维护前缀和即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=500005,mod=1e9;
    int n,a[N],ans=0,sm[N],sn[N],smi[N],sni[N],s[N],Mn[N],Mx[N],sum[N];
    inline void solve(int l,int r){
    	if(l==r){ans=(ans+1ll*a[l]*a[l])%mod;return ;}
    	int mid=(l+r)>>1;
    	solve(l,mid);solve(mid+1,r);
    	int mx=0,mn=mod,j=mid,k=mid;
    	s[mid]=sm[mid]=sn[mid]=smi[mid]=sni[mid]=Mx[mid]=0;Mn[mid]=mod;
    	for(int i=mid+1;i<=r;i++){
    		mx=max(mx,a[i]);mn=min(mn,a[i]);Mx[i]=mx;Mn[i]=mn;
    		sm[i]=(sm[i-1]+mx)%mod;sn[i]=(sn[i-1]+mn)%mod;
    		smi[i]=(smi[i-1]+1ll*mx*i)%mod;sni[i]=(sni[i-1]+1ll*mn*i)%mod;
    		s[i]=(s[i-1]+1ll*mx*mn%mod*i)%mod;sum[i]=(sum[i-1]+1ll*mx*mn)%mod;
    	}
    	mx=0;mn=mod;
    	for(int i=mid;i>=l;i--){
    		mx=max(mx,a[i]);mn=min(mn,a[i]);
    		while(j<r && Mn[j+1]>=mn)j++;
    		while(k<r && Mx[k+1]<=mx)k++;
    		int p=min(j,k),q=max(j,k);
    		ans=(ans+1ll*mx*mn%mod*((1ll*(mid-2*i+p+3)*(p-mid)>>1)%mod))%mod;
    		ans=(1ll*ans+s[r]-s[q]-1ll*(sum[r]-sum[q])*(i-1))%mod;
    		if(j<k)ans=(ans+1ll*mx*(1ll*sni[k]-sni[j]-1ll*(i-1)*(sn[k]-sn[j])%mod))%mod;
    		else ans=(ans+1ll*mn*(1ll*smi[j]-smi[k]-1ll*(i-1)*(sm[j]-sm[k])%mod))%mod;
    	}
    }
    int main(){
      freopen("pp.in","r",stdin);
      freopen("pp.out","w",stdout);
      scanf("%d",&n);
      for(int i=1;i<=n;i++)scanf("%d",&a[i]);
      solve(1,n);
      if(ans<0)ans+=mod;
      cout<<ans<<endl;
      return 0;
    }
    
    
  • 相关阅读:
    Microsoft Office MIME Types
    启动mongodb
    学习Hbase API的一个视频
    报错:Hive Runtime Error while processing row
    821. Shortest Distance to a Character
    1171. Remove Zero Sum Consecutive Nodes from Linked List
    190. Reverse Bits
    Rust--如何实现内存安全的?
    Rust -- as_ref与borrow的区别
    653. Two Sum IV
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8503261.html
Copyright © 2011-2022 走看看