#include #include const int oo = 2000000000; const int BLOCKSIZE = 700; const int MAXL = 500000+10; const int MAXBLOCK = MAXL/BLOCKSIZE*2+1000; void swap(int &a,int &b){a^=b;b^=a;a^=b;} int max(int a,int b){return a>b?a:b;} int min(int a,int b){return a count[b]; b=next[b]) p-=count[b]; } void maintainblock(int b){ if(same[b]){ totsum[b]=samevalue[b] * count[b]; if(samevalue[b]>0)maxsum[b]=totsum[b]; else maxsum[b]=samevalue[b]; sidemax[b][0]=sidemax[b][1]=maxsum[b]; }else{ totsum[b]=0;maxsum[b]=-oo; for(int last=0,i=count[b]-1; i>=0; --i){ totsum[b] += data[b][i]; last += data[b][i]; if(maxsum[b] < last)maxsum[b]=last; if(last < 0)last=0; } sidemax[b][0]=-oo; for(int last=0,i=0; i=0; --i){ last += data[b][i]; if(sidemax[b][1] < last)sidemax[b][1] = last; } } } void reverseblock(int b){ if(b==-1 || !reversed[b])return; reversed[b]=false; if(same[b])return; for(int l=0,r =count[b]-1; lcount[e]; e=next[e])n-=count[e]; splite(e,n); e=next[e]; for(int t=next[b]; t!=e; t=next[b]){ next[b]=next[t]; delnode(t); } } int list[MAXBLOCK]; void reverse(int p,int n){ int b,e,i,t; find(p,b); splite(b,p); for(e=next[b]; n>count[e]; e=next[e])n-=count[e]; splite(e,n); e=next[e]; for(i=0,t=next[b]; t!=e; t=next[t],++i)list[i]=t; next[b]=list[--i]; for(; i>=0; --i){ next[list[i]] = i ? list[i-1] : t; reversed[list[i]] = ! reversed[list[i]]; } maintainlist(b); } void makesame(int p,int n,int v){ int b,t; find(p,b); splite(b,p); for(t=next[b]; n>count[t]; n -= count[t],t=next[t]) fillblock(t, v, count[t], next[t]); if(n){ splite(t,n); fillblock(t, v, n, next[t]); } maintainlist(b); } int getsum_in_block(int b,int p,int n){ int sum,l,r; if(same[b])return samevalue[b] * n; if(reversed[b]){l = count[b] - p - n; r = count[b] - p - 1;} else {l = p; r = p + n - 1;} for(sum=0; l<=r; ++l)sum+=data[b][l]; return sum; } void getsum(int p,int n){ int b,t; find(p, b); int sum,i; sum=getsum_in_block(b, p, min(n, count[b] - p)); n -= min(n, count[b] - p); for(t=next[b]; n>count[t]; t=next[t]){ sum+=totsum[t]; n-=count[t]; } sum+=getsum_in_block(t, 0, n); printf("%d\n",sum); } void getmaxsum(){ int res=-oo,last=0; for(int b=0; b!=-1; b=next[b]){ res = max(res, last+sidemax[b][reversed[b]]); res = max(res, maxsum[b]); last= max(last+totsum[b], sidemax[b][!reversed[b]]); last= max(last, 0); } printf("%d\n",res); } void init(){ freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); for(int i=1; i