4487. Can you answer these queries VI - #include <Seter> - using namespace Orz;
4487. Can you answer these queries VI
http://www.spoj.pl/problems/GSS6/
ID | DATE | USER | PROBLEM | RESULT | TIME | MEM | LANG |
---|---|---|---|---|---|---|---|
6073829 | 2011-11-23 13:25:38 | Seter | Can you answer these queries VI |
accepted edit run |
8.28 | 12M |
C |
1A有木有!超开心……
某日看到fotile主席用4种方法在虐这题,深深被震撼,再次Orz!最神的一种方法是主席自己create的SBT进化版——主席树!主席说主席树可以秒杀一切神题!!!Orz!!!
这个是我A掉的第一个有一堆卫星数据的Splay题……留个念吧……
我对这种题木的唯一感觉就是Splay……空节点的特判我用null.l=null.r=-100000trick掉了,但是没敢插入头尾节点……所以在移动到第一个数前/最后一个数后的时候进行特判了囧……
Q的时候切掉1..i-1,j+1..s,update后输出整棵树的max就可以了……最后再将1..i-1接到最左边,j+1..s接到最右边……虽然这样有点慢但是我想不出更好的方法了T^T
彻底变傻X……可以splay第j个数,如果i=j则就是根的值,否则在左子树中splay第i个数,然后切掉它的左子树和根的右子树,update后再直接接回去……不过这样还是没tbl神犇快……改成C++就快了一点……不开O2其实还是C++快啊……
对一个节点(线段)记录lmax,rmax,max,sum。这四个用节点上的数推一下就可以了,很简单的……
注意改好后对修改的节点update啊……
另外没什么好说的……代码超长……70行TAT
#include <stdio.h> #include <string.h> #define maxn 200000 #define max(a,b) ((a)>(b)?(a):(b)) typedef struct _Splay{struct _Splay *c[2],*f;int s,v,l,r,m,a;}Splay,*PSplay; Splay null,st[maxn],*stp=st,*r=&null; char str[3000000],*p=str; inline PSplay update(PSplay x){ int ml=max(x->c[1]->l,0),mr=max(x->c[0]->r,0); x->s=x->c[0]->s+x->c[1]->s+1; x->a=x->c[0]->a+x->v+x->c[1]->a; x->l=max(x->c[0]->l,x->c[0]->a+x->v+ml); x->r=max(x->c[1]->r,x->c[1]->a+x->v+mr); return x->m=max(max(x->c[0]->m,x->c[1]->m),ml+x->v+mr),x; }inline PSplay rot(PSplay x){ PSplay fx=x->f,ffx=fx->f; _Bool c=fx->c[1]==x,fc=ffx->c[1]==fx; if(fx!=&null){ if((fx->c[c]=x->c[!c])!=&null)fx->c[c]->f=fx; if((x->f=ffx)!=&null)ffx->c[fc]=x; update((fx->f=x)->c[!c]=fx); }return x; }inline PSplay splay(PSplay x){ if(x==&null||x->f==&null)return update(x); for(;x->f!=&null;rot(x))if(x->f->f!=&null)rot((x->f->f->c[1]==x->f)==(x->f->c[1]==x)?x->f:x); return update(x); }inline PSplay Join(PSplay r1,PSplay r2){ if(r1==&null)return r2;if(r2==&null)return r1; while(r1->c[1]!=&null)r1=r1->c[1]; return update((splay(r1)->c[1]=r2)->f=r1); }inline PSplay Rank(PSplay r,int x){ _Bool c; if(x<=0||r->s<x)return &null; for(;;r=r->c[c])if(x==r->c[0]->s+1)return splay(r);else if(c=x>r->c[0]->s)x-=r->c[0]->s+1; }inline getint(){ int re=0;_Bool k; while(*p!='-'&&(*p<'0'||*p>'9'))p++; for(k=*p=='-'&&++p;*p>='0'&&*p<='9';)re=re*10+*p++-48; return k?-re:re; }main(){ int i,j;PSplay t1,t2;fread(str,1,3000000,stdin); for((null.f=null.c[0]=null.c[1]=&null)->m=null.l=null.r=-1000000,i=getint();i--;stp->v=getint(),r=update(stp++))if((stp->c[0]=r)!=(stp->c[1]=&null))r->f=stp;r->f=&null; while(1){ while(*++p<'A'||*p>'Z')if(!*p)return 0; if(*p=='Q'){ i=getint();t2=(r=Rank(r,j=getint()))->c[1]; if(i==j){printf("%d\n",r->v);continue;} r->c[1]=&null; if(i!=1){ r->c[0]->f=&null; t1=(r->c[0]=Rank(r->c[0],i))->c[0]; (r->c[0]->f=r)->c[0]->c[0]=&null; update(r->c[0]); }printf("%d\n",update(r)->m); if(i!=1)r->c[0]->c[0]=t1,update(r->c[0]); r->c[1]=t2;update(r); }else if(*p=='R')update(((r=Rank(r,getint()))->v=getint(),r)); else if(*p=='D'){ r=Rank(r,getint()); r->c[0]->f=r->c[1]->f=&null; r=Join(r->c[0],r->c[1]); }else if(stp->c[0]=stp->c[1]=&null,i=getint(),stp->v=getint(),i==r->s+1){ while(r->c[1]!=&null)r=r->c[1]; r=splay((stp->f=r)->c[1]=stp++); }else{ stp->c[0]=(stp->f=r=Rank(r,i))->c[0]; update(r->c[0]=r->c[0]->f=stp++);update(r); } } }
2011年12月02日 17:07
敢问fotile主席……鄙人弱菜神犇勿喷。
2011年12月02日 18:09
高一大神