bzoj 3745: [Coci2015]Norma【分治】
阿新 • • 發佈:2018-10-17
esp net sin bzoj main har min ret clu
參考:https://blog.csdn.net/lych_cys/article/details/51203960
真的不擅長這種……
分治,對於一個(l,r),先遞歸求出(l,mid),(mid+1,r),然後這個區間對答案貢獻的就是經過mid的區間
我們先預處理出mid為l的右端點的mx*mn*len的前綴和與mx*mn的前綴和,然後枚舉左端點,右端點維護兩個下標j,k,分別表示mn和mx在左端點時的合法右端點
然後分三種情況處理,假設j<k
1.右端點在(mid+1,j)時,直接計算
2.右端點在(j,k)時,相當於最小值在j,最大值在(j,k),預處理一個前綴和來計算
3.右端點在(k,r)時,直接用預處理的前綴和處理,要減去右端點在(mid+1,j)時的情況
#include<iostream> #include<cstdio> using namespace std; const int N=500005,mod=1e9; int n,ans,a[N],c[N][2],f[N],g[N],p[N][2],q[N][2]; int read() { int r=0,f=1; char p=getchar(); while(p>‘9‘||p<‘0‘) { if(p==‘-‘) f=-1; p=getchar(); } while(p>=‘0‘&&p<=‘9‘) { r=r*10+p-48; p=getchar(); } return r*f; } void jia(int &x,int y) { x+=y; x>=mod?x-=mod:0; } void jian(int &x,int y) { x-=y; x<0?x+=mod:0; } int clc(int x,int y) { return 1ll*(x+y)*(y-x+1)/2%mod; } void wk(int l,int r) { if(l==r) { jia(ans,1ll*a[l]*a[l]%mod); return; } int mid=(l+r)>>1; wk(l,mid); wk(mid+1,r); c[mid][0]=c[mid][1]=a[mid]; for(int i=mid-1;i>=l;i--) c[i][0]=min(c[i+1][0],a[i]),c[i][1]=max(c[i+1][1],a[i]); int mn=1e9,mx=-1e9; f[mid]=g[mid]=p[mid][0]=p[mid][1]=q[mid][0]=q[mid][1]=0; for(int i=mid+1;i<=r;i++) { mn=min(mn,a[i]),mx=max(mx,a[i]); f[i]=1ll*mn*mx%mod*(i-mid)%mod; jia(f[i],f[i-1]); g[i]=1ll*mn*mx%mod; jia(g[i],g[i-1]); p[i][0]=(p[i-1][0]+mn)%mod; q[i][0]=(q[i-1][0]+mx)%mod; p[i][1]=1ll*mn*(i-mid)%mod; jia(p[i][1],p[i-1][1]); q[i][1]=1ll*mx*(i-mid)%mod; jia(q[i][1],q[i-1][1]); } for(int i=mid,j=mid,k=mid;i>=l;i--) { while(j<r&&c[i][0]<a[j+1]) j++; while(k<r&&c[i][1]>a[k+1]) k++; jia(ans,1ll*c[i][0]*c[i][1]%mod*clc(mid-i+2,min(j,k)-i+1)%mod); jia(ans,(1ll*g[r]*(mid-i+1)+f[r])%mod); jian(ans,(1ll*g[max(j,k)]*(mid-i+1)+f[max(j,k)])%mod); if(j<k) { jia(ans,(1ll*p[k][0]*(mid-i+1)+p[k][1])%mod*c[i][1]%mod); jian(ans,(1ll*p[j][0]*(mid-i+1)+p[j][1])%mod*c[i][1]%mod); } else { jia(ans,(1ll*q[j][0]*(mid-i+1)+q[j][1])%mod*c[i][0]%mod); jian(ans,(1ll*q[k][0]*(mid-i+1)+q[k][1])%mod*c[i][0]%mod); } } } int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(); wk(1,n); printf("%d\n",ans); return 0; }
bzoj 3745: [Coci2015]Norma【分治】