码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 2843: 极地旅行社 lct splay

时间:2018-03-24 14:28:24      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:需要   旅行社   scan   分享   zoj   amp   using   lin   https   

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 }
View Code

 

 

BZOJ 2843: 极地旅行社 lct splay

标签:需要   旅行社   scan   分享   zoj   amp   using   lin   https   

原文地址:https://www.cnblogs.com/137shoebills/p/8638623.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!