[NOI2005]维护数列
[NOI2005]维护数列
这题怕是会记忆一辈子吧QWQ
调了大概一天一夜233333
wa了整整一面之后,然后发现l打成r了
特别高兴,交上去之后洛谷过了,然后bzojTLE了
然后又找了很长很长时间,以为那里死循环了。。。
等后一天颓了很长很长时间后,鬼使神差地点开了discuss,然后发现有大佬跟我一样t了
然后抱着一种死马当活马医的心态改小了数组范围,然后。。。
然后就a了。。。幼小
#include<bits/stdc++.h> #define MAXN 5000010 using namespace std; const int inf=0x3f3f3f3f; int k,sum1,val; char ch[10]; int n,m,rt,cnt; int a[MAXN],num[MAXN],fa[MAXN],f[MAXN][2]; int sum[MAXN],size[MAXN],v[MAXN],mx[MAXN],l[MAXN],r[MAXN]; bool tf[MAXN],pf[MAXN]; queue<int> q; // inline int read() { // char ch; // bool f=false; // int res=0; // while (((ch=getchar())<'0'||ch>'9')&&ch!='-'); // if (ch=='-') // f=true; // else // res=ch-'0'; // while ((ch=getchar())>='0'&&ch<='9') // res=(res<<3)+(res<<1)+ch-'0'; // return f?~res+1:res; // } inline void update(int x){ sum[x]=sum[f[x][0]]+sum[f[x][1]]+v[x]; size[x]=size[f[x][0]]+size[f[x][1]]+1; mx[x]=max(mx[f[x][0]],max(mx[f[x][1]],r[f[x][0]]+v[x]+l[f[x][1]])); l[x]=max(l[f[x][0]],sum[f[x][0]]+v[x]+l[f[x][1]]); r[x]=max(r[f[x][1]],sum[f[x][1]]+v[x]+r[f[x][0]]); } inline void s1(int t,int w,int x){ tf[t]=1,v[t]=v[x],sum[t]=v[x]*size[t]; } inline void s2(int t){ l[t]=r[t]=mx[t]=sum[t]; } inline void s3(int t,int x){ l[t]=r[t]=0,mx[t]=v[x]; } inline void s4(int x){ int t=f[x][0],w=f[x][1]; if (tf[x]){ pf[x]=tf[x]=0; if (t) s1(t,w,x); if (w) s1(w,t,x); /*if (v[x]>=0&&t) s2(t); if (v[x]>=0&&w) s2(w); if (v[x]<0&&t) s3(t,x); if (v[x]<0&&w) s3(w,x); */ if (v[x]>=0){ if(t) s2(t); if (w) s2(w); } else { if (t) s3(t,x); if (w) s3(w,x); } } if(pf[x]){ pf[x]=0; pf[t]^=1; pf[w]^=1; swap(l[t],r[t]); swap(l[w],r[w]); swap(f[t][0],f[t][1]); swap(f[w][0],f[w][1]); } } inline void rotate(int x,int &k){ int y=fa[x],z=fa[y],t,w; s4(x),s4(y); /*if (f[y][1]==x) t=1; else t=0; w=t^1; k=(y==k)?x:k; if (y!=k) //f[z][1]=y,f[z][y]=x; f[z][f[z][1]==y]=x;*/ t=(f[y][1]==x); w=t^1; if (y==k) k=x; else f[z][f[z][1]==y]=x; fa[f[x][w]]=y,fa[y]=x,fa[x]=z; f[y][t]=f[x][w]; f[x][w]=y; update(y); update(x); } inline void splay(int x,int &k){ while (x!=k){ int y=fa[x],z=fa[y]; if (y!=k){ //rotate(((f[y][0]==x^f[z][0]==y)?x:y),k); if (f[z][0]==y^f[y][0]==x)rotate(x,k); else rotate(y,k); } rotate(x,k); } } inline int find (int x,int rk){ s4(x); int t=f[x][0],w=f[x][1]; if (size[t]+1==rk) return x; if (size[t]>=rk) return find(t,rk); else return find(w,rk-size[t]-1); } inline void clean(int x){ q.push(x); fa[x]=f[x][0]=f[x][1]=0; tf[x]=pf[x]=0; } inline void rec(int x){ /*if (!x) return; int t=f[x][0],w=f[x][1]; rec(t); rec(w); //clean(x);*/ int &t=f[x][0],&w=f[x][1]; if (t) rec(t); if (w) rec(w); q.push(x); fa[x]=t=w=tf[x]=pf[x]=0; } inline int split(int t,int sum1){ int x=find(rt,t),y=find(rt,t+sum1+1); splay(x,rt); splay(y,f[x][1]); return f[y][0]; } inline void query(int k,int sum1){ int x=split(k,sum1); printf("%d\n",sum[x]); } inline void modify(int k,int sum1,int val){ int x=split(k,sum1),y=fa[x]; v[x]=val,tf[x]=1,sum[x]=size[x]*val; /*l[x]=r[x]=((val>=0)?sum[x]:0); mx[x]=((val>=0)?sum[x]:val);*/ if (val>=0) l[x]=r[x]=mx[x]=sum[x]; else l[x]=r[x]=0,mx[x]=val; update(y); update(fa[y]); } inline void pfer(int k,int sum1){ int x=split(k,sum1),y=fa[x]; if (!tf[x]){ pf[x]^=1; swap(f[x][0],f[x][1]); swap(l[x],r[x]); update(y); update(fa[y]); } } inline void erase(int k,int sum1){ int x=split(k,sum1),y=fa[x]; rec(x); f[y][0]=0; update(y); update(fa[y]); } inline void build(int t,int w,int k){ int mid=(t+w)>>1; int now=num[mid],last=num[k]; if (t==w){ mx[now]=sum[now]=a[t]; tf[now]=pf[now]=0; l[now]=r[now]=max(a[t],0); size[now]=1; } if (t<mid)build(t,mid-1,mid); if (mid<w)build(mid+1,w,mid); v[now]=a[mid]; fa[now]=last; //printf("error: %d\n",now); update(now); f[last][mid>=k]=now; } inline void insert(int k,int sum1){ for (int i=1;i<=sum1;++i) //a[i]=read(); scanf("%d",&a[i]); for (int i=1;i<=sum1;++i) if (!q.empty()) num[i]=q.front(),q.pop(); else num[i]=++cnt; build(1,sum1,0); int z=num[(1+sum1)>>1],x=find(rt,k+1),y=find(rt,k+2); splay(x,rt); splay(y,f[x][1]); fa[z]=y; f[y][0]=z; update(y); update(x); } void liblibal(int x){ if(!x)return; s4(x); liblibal(f[x][0]); printf("%d ",a[x]); liblibal(f[x][1]); } int main(){ //freopen("","r",stdin); //freopen("","w",stdout); /*n=read(),m=read(),*/scanf("%d%d",&n,&m); mx[0]=a[1]=a[n+2]=-inf,rt=(n+3)>>1,cnt=n+2; for (int i=1;i<=n;++i) scanf("%d",&a[i+1]); //a[i+1]=read(); for (int i=1;i<=n+2;++i) num[i]=i; build(1,n+2,0); while(m--){ scanf("%s",ch); if(ch[0]!='M'||ch[2]!='X') /*k=read()*/scanf("%d%d",&k,&sum1)/*,sum1=read()*/; if(ch[0]=='I') insert(k,sum1); if(ch[0]=='D') erase(k,sum1); if(ch[0]=='M'){ if(ch[2]=='X') printf("%d\n",mx[rt]); else { /*val=read()*/scanf("%d",&val); modify(k,sum1,val); } } if(ch[0]=='R') pfer(k,sum1); if(ch[0]=='G') query(k,sum1); //liblibal(rt); } return 0; }