就是很裸的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;
}