您的位置:首页 > 其它

【BZOJ 1180】 (LCT)

2017-04-27 10:50 204 查看

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: