【BZOJ 1180】 (LCT)

1180: [CROATIAN2009]OTOCI

Time Limit: 50 Sec  Memory Limit: 162 MB
Submit: 1078  Solved: 662

Description

给出n个结点以及每个点初始时对应的权值wi。起始时点与点之间没有连边。有3类操作: 1、bridge A B:询问结点A与结点B是否连通。如果是则输出“no”。否则输出“yes”,并且在结点A和结点B之间连一条无向边。 2、penguins A X:将结点A对应的权值wA修改为X。 3、excursion A B:如果结点A和结点B不连通,则输出“impossible”。否则输出结点A到结点B的路径上的点对应的权值的和。给出q个操作,要求在线处理所有操作。数据范围:1<=n<=30000, 1<=q<=300000, 0<=wi<=1000。

Input

第一行包含一个整数n(1<=n<=30000),表示节点的数目。第二行包含n个整数,第i个整数表示第i个节点初始时对应的权值。第三行包含一个整数q(1<=n<=300000),表示操作的数目。以下q行,每行包含一个操作,操作的类别见题目描述。任意时刻每个节点对应的权值都是1到1000的整数。

Output

输出所有bridge操作和excursion操作对应的输出,每个一行。

Sample Input

5
4 2 4 5 6
10
excursion 1 1
excursion 1 2
bridge 1 2
excursion 1 2
bridge 3 4
bridge 3 5
excursion 4 5
bridge 1 3
excursion 2 4
excursion 2 5

Sample Output

4
impossible
yes
6
yes
yes
15
yes
15
16

HINT

Source

 

 

【分析】

  LCT裸题。。

  没有cut操作。。

  嗯。。。还是要调试啊。。。

  注意LCT是维护链的,,询问路径对LCT来说就是小菜一碟。。

  不过之前维护子树的那题用LCT变成路径维护的感觉很强啊。。

 

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7 #define Maxn 30010
  8 
  9 struct node
 10 {
 11     int son[2],fa,w,sm;
 12     bool rev;
 13     node() {son[0]=son[1]=fa=w=sm=rev=0;}
 14 }tr[Maxn];
 15 
 16 int q[Maxn],ql;
 17 struct LCT
 18 {
 19     void upd(int x)
 20     {
 21         int lc=tr[x].son[0],rc=tr[x].son[1];
 22         tr[x].sm=tr[lc].sm+tr[rc].sm+tr[x].w;
 23     }
 24     void push_down(int x)
 25     {
 26         int lc=tr[x].son[0],rc=tr[x].son[1];
 27         if(tr[x].rev)
 28         {
 29             swap(tr[x].son[0],tr[x].son[1]);
 30             tr[lc].rev^=1;tr[rc].rev^=1;
 31             tr[x].rev=0;
 32         }
 33     }
 34     bool is_root(int x)
 35     {
 36         return tr[tr[x].fa].son[0]!=x&&tr[tr[x].fa].son[1]!=x;
 37     }
 38     void rot(int x)
 39     {
 40         int fa=tr[x].fa,yy=tr[fa].fa;
 41         int w=tr[fa].son[0]==x?1:0;
 42         
 43         if(!is_root(fa))
 44         {
 45             if(tr[yy].son[0]==fa) tr[yy].son[0]=x;
 46             else tr[yy].son[1]=x;
 47         }tr[x].fa=yy;
 48         
 49         tr[tr[x].son[w]].fa=fa;
 50         tr[fa].son[1-w]=tr[x].son[w];
 51         
 52         tr[x].son[w]=fa;
 53         tr[fa].fa=x;
 54         upd(fa);//upd(x);
 55     }
 56     void pre(int x)
 57     {
 58         ql=0;
 59         while(!is_root(x)) q[++ql]=x,x=tr[x].fa;
 60         q[++ql]=x;
 61         while(ql) push_down(q[ql--]);
 62     }
 63     void splay(int x)
 64     {
 65         pre(x);
 66         while(!is_root(x))
 67         {
 68             int fa=tr[x].fa,yy=tr[fa].fa;
 69             if(!is_root(fa))
 70             {
 71                 if((tr[yy].son[0]==fa)==(tr[fa].son[0]==x)) rot(fa);
 72                 else rot(x);
 73             }
 74             rot(x);
 75         }upd(x);
 76     }
 77     void access(int x)
 78     {
 79         int lt=0;
 80         while(x)
 81         {
 82             splay(x);
 83             tr[x].son[1]=lt;
 84             upd(x);
 85             lt=x;
 86             x=tr[x].fa;
 87         }
 88     }
 89     void make_root(int x)
 90     {
 91         access(x);
 92         splay(x);
 93         tr[x].rev^=1;
 94     }
 95     void split(int x,int y)
 96     {
 97         make_root(x);
 98         access(y);
 99         splay(y);
100     }
101     int find_root(int x)
102     {
103         access(x);
104         splay(x);
105         while(tr[x].son[0]) x=tr[x].son[0];
106         return x;
107     }
108     bool cn(int x,int y)
109     {
110         return find_root(x)==find_root(y);
111     }
112     void link(int x,int y)
113     {
114         make_root(x);
115         tr[x].fa=y;
116     }
117 }LCT;
118 
119 char s[20];
120 
121 int main()
122 {
123     int n;
124     scanf("%d",&n);
125     for(int i=1;i<=n;i++)
126     {
127         int x;
128         scanf("%d",&x);
129         tr[i].w=x;LCT.upd(x);
130     }
131     int q;
132     scanf("%d",&q);
133     while(q--)
134     {
135         int x,y;
136         scanf("%s%d%d",s,&x,&y);
137         if(s[0]=='e')
138         {
139             if(!LCT.cn(x,y)) printf("impossible\n");
140             else
141             {
142                 LCT.split(x,y);
143                 printf("%d\n",tr[y].sm);
144             }
145         }
146         else if(s[0]=='b')
147         {
148             if(!LCT.cn(x,y)) {printf("yes\n");LCT.link(x,y);}
149             else printf("no\n");
150         }
151         else
152         {
153             LCT.splay(x);
154             tr[x].w=y;LCT.upd(x);
155         }
156     }
157     return 0;
158 }
View Code

 

2017-04-27 10:50:31

posted @ 2017-04-27 10:50  konjak魔芋  阅读(278)  评论(0编辑  收藏  举报