BZOJ 2843: 极地旅行社 lct splay
http://www.lydsy.com/JudgeOnline/problem.php?id=2843
https://blog.csdn.net/clove_unique/article/details/50992341
和之前那道题lct求两点距离用lca不同,这道题因为给的边的两个端点是没有顺序的(没法直接按照给的点直接将某个点连到树上),所以bridge需要区间翻转的操作,因为splay维护的是链,所以区间翻转相当于将叶子变成了根,根变成叶子(链翻转过来),然后再把此时的根(x)连到y上就可以了。
penguins操作之后要access一下
excursion操作时,将x翻转为根再access y就能求出这一段上的企鹅数。。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int maxn=30010; 8 int n,m; char f[12]={}; 9 int fa[maxn]={},ch[maxn][2]={},siz[maxn]={}; 10 int val[maxn]={},rev[maxn]={}; 11 int sta[maxn]={},tail=0; 12 int ds[maxn]={}; 13 inline void updata(int x){ siz[x] = siz[ch[x][0]] + siz[ch[x][1]]+val[x];} 14 inline bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} 15 int getfa(int x){if(ds[x]==x)return x; return ds[x]=getfa(ds[x]);} 16 void rotate(int x){ 17 int y=fa[x];int fy=fa[y]; 18 int l=ch[y][0]==x?0:1;int r=l^1; 19 if(!isroot(y)){ 20 if(ch[fy][0]==y) ch[fy][0]=x; 21 else ch[fy][1]=x; 22 } 23 fa[ch[x][r]]=y;fa[x]=fy;fa[y]=x; 24 ch[y][l]=ch[x][r];ch[x][r]=y; 25 updata(y); 26 } 27 void Swapdata(int x){ 28 if(rev[x]){ 29 swap(ch[x][0],ch[x][1]); 30 if(ch[x][0])rev[ch[x][0]]^=1; 31 if(ch[x][1])rev[ch[x][1]]^=1; 32 rev[x]=0; 33 } 34 } 35 void splay(int x){ 36 int w=x; 37 int y,fy;sta[++tail]=x; 38 while(w&&!isroot(w)){sta[++tail]=fa[w];w=fa[w];} 39 while(tail){Swapdata(sta[tail--]);} 40 while(!isroot(x)){ 41 y=fa[x];fy=fa[y]; 42 if(!isroot(y)){ 43 if((ch[fy][0]==y)^(ch[y][0]==x))rotate(x); 44 else rotate(y); 45 }rotate(x); 46 }updata(x); 47 } 48 void Access(int x){ 49 int y=0; 50 while(x){ 51 splay(x); 52 ch[x][1]=y; 53 updata(x); 54 y=x;x=fa[y]; 55 } 56 } 57 void Reverse(int x){ 58 Access(x); 59 splay(x); 60 rev[x]^=1; 61 } 62 void Link(int x,int y){ 63 Reverse(x);fa[x]=y; 64 splay(x); 65 } 66 int main(){ 67 scanf("%d",&n); 68 for(int i=1;i<=n;i++)scanf("%d",&val[i]); 69 for(int i=1;i<=n;i++)ds[i]=i; 70 scanf("%d",&m); 71 int x,y,xx,yy; 72 for(int i=1;i<=m;i++){ 73 scanf("%s",f); 74 scanf("%d%d",&x,&y); 75 if(f[0]=='b'){ 76 xx=getfa(x);yy=getfa(y); 77 if(xx==yy)printf("no\n"); 78 else{ 79 printf("yes\n");ds[xx]=yy; 80 if(x!=y)Link(x,y); 81 } 82 } 83 else if(f[0]=='p'){ 84 val[x]=y;Access(x);splay(x); 85 } 86 else{ 87 xx=getfa(x);yy=getfa(y); 88 if(xx!=yy)printf("impossible\n"); 89 else{ 90 Reverse(x);Access(y);splay(y); 91 printf("%d\n",siz[y]); 92 } 93 } 94 } 95 return 0; 96 }