1. 程式人生 > >1180: [CROATIAN2009]OTOCI(LCT)

1180: [CROATIAN2009]OTOCI(LCT)

nbsp time rotate har 一行 ces oid scan gre

1180: [CROATIAN2009]OTOCI

Time Limit: 50 Sec Memory Limit: 162 MB
Submit: 1200 Solved: 747
[Submit][Status][Discuss]

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

code

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 const int N = 50010;
 7 
 8 int val[N],fa[N],ch[N][2
],rev[N],sum[N],st[N],top; 9 10 void pushup(int x) { 11 sum[x] = sum[ch[x][1]] + sum[ch[x][0]] + val[x]; 12 } 13 void pushdown(int x) { 14 int l = ch[x][0],r = ch[x][1]; 15 if (rev[x]) { 16 rev[l] ^= 1;rev[r] ^= 1; 17 swap(ch[x][0],ch[x][1]); 18 rev[x] ^= 1; 19 } 20 } 21 bool isroot(int x) { 22 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 23 } 24 int son(int x) { 25 return ch[fa[x]][1]==x; 26 } 27 void rotate(int x) { 28 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 29 if (!isroot(y)) ch[z][c] = x;fa[x] = z; 30 ch[x][!b] = y;fa[y] = x; 31 ch[y][b] = a;if (a) fa[a] = y; 32 pushup(y);pushup(x); 33 } 34 void splay(int x) { 35 top = 0;st[++top] = x; 36 for (int i=x; !isroot(i); i=fa[i]) st[++top] = fa[i]; 37 while (top) pushdown(st[top--]); 38 while (!isroot(x)) { 39 int y = fa[x]; 40 if (!isroot(y)) { 41 if (son(x)==son(y)) rotate(y); 42 else rotate(x); 43 } 44 rotate(x); 45 } 46 } 47 void access(int x) { 48 for (int t=0; x; t=x,x=fa[x]) { 49 splay(x);ch[x][1] = t;pushup(x); 50 } 51 } 52 void makeroot(int x) { 53 access(x); 54 splay(x); 55 rev[x] ^= 1; 56 } 57 void link(int x,int y) { 58 makeroot(x); 59 fa[x] = y; 60 } 61 void update(int x,int y) { 62 makeroot(x);val[x] = y;pushup(x); 63 } 64 int query(int x,int y) { 65 makeroot(x);access(y);splay(y); 66 return sum[y]; 67 } 68 int find(int x) { 69 access(x);splay(x); 70 while (ch[x][0]) x = ch[x][0]; 71 return x; 72 } 73 int main() { 74 int n,m,x,y; 75 char opt[20]; 76 scanf("%d",&n); 77 for (int i=1; i<=n; ++i) scanf("%d",&val[i]),sum[i] = val[i]; 78 scanf("%d",&m); 79 while (m--) { 80 scanf("%s%d%d",opt,&x,&y); 81 if (opt[0]==b) { 82 if (find(x)==find(y)) puts("no"); 83 else puts("yes"),link(x,y); 84 } 85 else if (opt[0]==p) update(x,y); 86 else { 87 if (find(x)!=find(y)) puts("impossible"); 88 else printf("%d\n",query(x,y)); 89 } 90 } 91 return 0; 92 }

1180: [CROATIAN2009]OTOCI(LCT)