bzoj2843
就是很裸的lct,犯的错误已经在代码中标出。
(学校食堂今天的八宝粥是糊的)
(bzoj 3091需要这个代码的对照)
2015.9.11:
注意修改数据时,要考虑对于现在的结构造成的影响,所以某个节点的数据修改前,考虑需不需要access()(感觉怎么这么像需求管理中的需求变更?好像暴露专业了)
//感觉只要任何时刻任何两点之间都只有一条路的话,好像可以用lct #include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 30010 struct node{ node *fa;//这里一开始不要赋值 node *ch[2]; int val; int root; int sum; int valnum; int rev; void init(int tempval,int tempvalnum){ val=tempval; valnum=tempvalnum; sum=valnum; root=val; ch[0]=NULL; ch[1]=NULL; fa=NULL; rev=0; } bool isroot(){ /*if(!(fa->ch[1])){ printf("wo shi da hao ren"); } printf("wo shi da hao ren");*///调错:不明白这里为什么只要涉及到fa->ch[0]和fa-ch[1]就会出错 /*if(fa==NULL){ printf("wo shi da hao ren"); }*///调错:fa要么等于NULL,要么不等于NULL,为什么这里无论等于还是不等于都不输出呢? return fa==NULL||(fa->ch[0]!=this&&fa->ch[1]!=this); } void fswitch(){ rev^=1; swap(ch[0],ch[1]); } void push_down(){ if(rev){ if(ch[0]){ ch[0]->fswitch(); } if(ch[1]){ ch[1]->fswitch(); } rev=0; } return; } void go(){ if(!isroot()){//这里是isroot,不是fa->isroot(),这里的错会在isroot处停止执行 fa->go(); } push_down(); return; } int dir(){ return fa->ch[1]==this?1:0; } void setedge(int d,node *another){ ch[d]=another; if(another){ another->fa=this; } } void push_up(){ sum=valnum; if(ch[0]){ root=ch[0]->root; sum+=ch[0]->sum; } else{ root=val; } if(ch[1]){ sum+=ch[1]->sum; } } void rot(){ int d=dir(); node *tempfafa=fa->fa; if(!(fa->isroot())){ tempfafa->ch[fa->dir()]=this; } fa->setedge(d,ch[!d]); setedge(!d,fa); fa=tempfafa; ch[!d]->push_up(); return; } void splay(){ go();//这里没回来printf("wo shi da hao ren"); while(!isroot()){ if(!(fa->isroot())){ dir()==fa->dir()?fa->rot():rot(); } rot(); } push_up(); return; } void access(){ for(node *p=this,*q=NULL;p!=NULL;q=p,p=p->fa){ p->splay();//调错:这里没回来printf("wo shi da hao ren"); p->setedge(1,q); p->push_up(); } splay(); return; } void make_root(){ access();//调错:这里是access不是rev^=1,这里没回来printf("wo shi da hao ren"); fswitch(); } void cut(node *another){ make_root(); another->access(); another->ch[0]->fa=NULL; another->ch[0]=NULL; another->push_up(); return; } void link(node *another){ another->make_root(); another->fa=this; return; } bool islink(node *another){ make_root();//调错:make_root()函数改了以后,是这里就没回来 another->access();//调错:这里没回来printf("wo shi da hao ren"); if(another->root==this->val){ return true; } else{ return false; } } int query(node *another){ make_root(); another->access(); return another->sum; } void change(int tempvalnum){ access(); valnum=tempvalnum;//这句没写,所以wr了 sum=tempvalnum; if(ch[0]){ sum+=ch[0]->sum; } return; } }; node *tree[N],pool[N]; int main(){ int n; int m; int a,b; char op[20]; while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d",&a); tree[i]=&(pool[i]); tree[i]->init(i,a); } scanf("%d",&m); for(int i=0;i<m;i++){ scanf("%s%d%d",op,&a,&b); if(op[0]=='b'){ if(tree[a]->islink(tree[b])){ printf("no\n"); } else{ printf("yes\n"); tree[a]->link(tree[b]); } } else if(op[0]=='p'){ tree[a]->change(b); } else{ if(tree[a]->islink(tree[b])){ printf("%d\n",tree[a]->query(tree[b])); } else{ printf("impossible\n"); } } } } return 0; }