bzoj1500: [NOI2005]维修数列
模板题
之前还写了点铺垫题
bzoj3223 教你如何reverse
bzoj1507 教你如何维护序列
bzoj1269 教你如何维护序列&reverse
然后再做这个题就好多啦
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #define N 500005 using namespace std; inline int read(){ int ret=0;char ch=getchar(); bool flag=0; while (ch<'0' || ch>'9'){ flag=ch=='-'; ch=getchar(); } while ('0'<=ch && ch<='9'){ ret=ret*10-48+ch; ch=getchar(); } return flag?-ret:ret; } struct Splay{ #define ls(a) (t[a].c[0]) #define rs(a) (t[a].c[1]) int root; int q[4000006],qh,qt; struct SPLAYnode{ int c[2],fa,size; int data,sum,lsum,rsum,maxsum; bool rev,tag;int num; } t[N]; int newnode(){ int ret=q[++qh]; t[ret].fa=ls(ret)=rs(ret)=t[ret].rev=t[ret].tag=0; t[ret].size=1; return ret; } void load(){ qh=qt=0; ls(0)=rs(0)=t[0].rev=t[0].tag=t[0].sum=t[0].lsum=t[0].rsum=t[0].maxsum=0; t[1].data=-1001; for (int i=1;i<=500000;++i) q[++qt]=i; t[root=newnode()].size=1; } void renew(int x){ t[x].size=t[ls(x)].size+t[rs(x)].size+1; t[x].sum=t[ls(x)].sum+t[rs(x)].sum+t[x].data; t[x].lsum=t[ls(x)].sum+t[x].data+max(t[rs(x)].lsum,0); if (ls(x)) t[x].lsum=max(t[x].lsum,t[ls(x)].lsum); t[x].rsum=t[rs(x)].sum+t[x].data+max(t[ls(x)].rsum,0); if (rs(x)) t[x].rsum=max(t[x].rsum,t[rs(x)].rsum); t[x].maxsum=t[x].data+max(t[ls(x)].rsum,0)+max(t[rs(x)].lsum,0); if (ls(x)) t[x].maxsum=max(t[x].maxsum,t[ls(x)].maxsum); if (rs(x)) t[x].maxsum=max(t[x].maxsum,t[rs(x)].maxsum); } int f(int x){return (ls(t[x].fa)!=x)*(1-2*(rs(t[x].fa)!=x));} void fill(int x,int value){ t[x].tag=1;t[x].num=value; t[x].data=value; t[x].sum=value*t[x].size; t[x].lsum=t[x].rsum=t[x].maxsum=max(t[x].sum,value); } void rever(int x){ t[x].rev^=1; swap(ls(x),rs(x)); swap(t[x].lsum,t[x].rsum); } void PushDown(int x){ if (t[x].rev){ t[x].rev^=1; rever(ls(x)); rever(rs(x)); } if (t[x].tag){ if (ls(x)) fill(ls(x),t[x].num); if (rs(x)) fill(rs(x),t[x].num); t[x].tag=0; } } void rotate(int x){ int y=t[x].fa,z=t[y].fa,k=f(x),fz=f(y); if (fz>=0) t[z].c[fz]=x; t[y].c[k]=t[x].c[k^1];t[x].c[k^1]=y; t[t[y].c[k]].fa=y;t[x].fa=z;t[y].fa=x; renew(y);renew(x); } int stack[N],top; void splay(int x){ top=0;stack[top++]=x; for (int i=x;f(i)>=0;i=t[i].fa) stack[top++]=t[i].fa; while (top) PushDown(stack[--top]); for (root=x;f(x)>=0;rotate(x)) if (f(t[x].fa)==f(x)) rotate(t[x].fa); else if (f(t[x].fa)>=0) rotate(x); } int findk(int k){ int x=root; for (PushDown(x);t[ls(x)].size+1!=k;PushDown(x)) if (t[ls(x)].size+1<k){ k-=t[ls(x)].size+1; x=rs(x); } else x=ls(x); return x; } void reverse(int l,int r){ l=findk(l);r=findk(r); splay(l);int tmpl=ls(l);ls(l)=0;renew(l); splay(r);int tmpr=rs(r);rs(r)=0;renew(r); rever(r); splay(l);t[rs(l)=tmpr].fa=l;renew(l); splay(r);t[ls(r)=tmpl].fa=r;renew(r); } void ins(int cnt){ int now=0; while (cnt--){ int tmp=newnode(); t[now].fa=tmp; t[tmp].data=read(); ls(tmp)=now; renew(now=tmp); } PushDown(root); int tmp=rs(root); PushDown(tmp); rs(now)=tmp;t[tmp].fa=now;renew(now); rs(root)=now;t[now].fa=root;renew(root); } void release(int x){ if (!x) return; q[++qt]=x; release(ls(x)); release(rs(x)); } void del(int l,int r){ l=findk(l);r=findk(r); splay(r);int tmp=rs(r);rs(r)=0;renew(r); splay(l);swap(rs(l),tmp);t[rs(l)].fa=l;renew(l); release(tmp); } void update(int l,int r){ l=findk(l);r=findk(r); splay(l);int tmpl=ls(l);ls(l)=0;renew(l); splay(r);int tmpr=rs(r);rs(r)=0;renew(r); fill(r,read()); splay(l);t[ls(l)=tmpl].fa=l;renew(l); splay(r);t[rs(r)=tmpr].fa=r;renew(r); } void getsum(int l,int r){ if (l>r){puts("0");return;} l=findk(l);r=findk(r); splay(l);int tmpl=ls(l);ls(l)=0;renew(l); splay(r);int tmpr=rs(r);rs(r)=0;renew(r); printf("%d\n",t[r].sum); splay(l);t[ls(l)=tmpl].fa=l;renew(l); splay(r);t[rs(r)=tmpr].fa=r;renew(r); } } s; int main(){ s.load();int now=1,tmp=read(),Q=read(); s.ins(tmp); while (Q--){ char op=getchar(); while (!isalpha(op)) op=getchar(); char op2=getchar();op2=getchar(); if (op=='M'&&op2=='X'){ printf("%d\n",s.t[s.root].maxsum); for (int i=0;i<4;++i) getchar(); continue; } s.splay(s.findk(now=read()+1)); if (op=='M') s.update(now,now+read()-1); else if (op=='R') s.reverse(now,now+read()-1); else if (op=='I') s.ins(read()); else if (op=='D') s.del(now-1,now+read()-1); else if (op=='G') s.getsum(now,now+read()-1); } return 0; }
到现在刚学splay,还是太弱了TAT