4487. Can you answer these queries VI - #include <Seter> - using namespace Orz;

4487. Can you answer these queries VI

Seter posted @ 2011年11月23日 20:58 in SPOJ with tags BalancedTree Classical Splay , 2851 阅读

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);
		}
	}
}

 

By Seter
jiangzoi 说:
2011年12月02日 17:07

敢问fotile主席……鄙人弱菜神犇勿喷。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter
Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee