bzoj1180: [CROATIAN2009]OTOCI

Description

給出n個結點以及每一個點初始時對應的權值wi。起始時點與點之間沒有連邊。有3類操做: 一、bridge A B:詢問結點A與結點B是否連通。若是是則輸出「no」。不然輸出「yes」,而且在結點A和結點B之間連一條無向邊。 二、penguins A X:將結點A對應的權值wA修改成X。 三、excursion A B:若是結點A和結點B不連通,則輸出「impossible」。不然輸出結點A到結點B的路徑上的點對應的權值的和。給出q個操做,要求在線處理全部操做。數據範圍:1<=n<=30000, 1<=q<=300000, 0<=wi<=1000。ios

Input

第一行包含一個整數n(1<=n<=30000),表示節點的數目。第二行包含n個整數,第i個整數表示第i個節點初始時對應的權值。第三行包含一個整數q(1<=n<=300000),表示操做的數目。如下q行,每行包含一個操做,操做的類別見題目描述。任意時刻每一個節點對應的權值都是1到1000的整數。git

Output

輸出全部bridge操做和excursion操做對應的輸出,每一個一行。ui

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
 
 
題解:
  LCT模板題·····練手用的······
code:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch; bool ok;
 8 void read(int &x){
 9     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
10     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
11     if (ok) x=-x;
12 }
13 const int maxn=100005;
14 int n,q,x,y;
15 char op[10];
16 struct LCT{
17     #define ls son[x][0]
18     #define rs son[x][1]
19     int fa[maxn],son[maxn][2],rev[maxn],val[maxn],sum[maxn];
20     int which(int x){return son[fa[x]][1]==x;}
21     bool isroot(int x){return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;}
22     void addtag_rev(int x){if (x) rev[x]^=1,swap(ls,rs);}
23     void pushdown(int x){if (rev[x]) addtag_rev(ls),addtag_rev(rs),rev[x]=0;}
24     void relax(int x){
25         if (!isroot(x)) relax(fa[x]);
26         pushdown(x);    
27     }
28     void updata(int x){sum[x]=sum[ls]+val[x]+sum[rs];}
29     void rotate(int x){
30         int y=fa[x],z=fa[y],d=which(x),dd=which(y);
31         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],fa[x]=fa[y];
32         if (!isroot(y)) son[z][dd]=x;
33         son[x][d^1]=y,fa[y]=x,updata(y);    
34     }
35     void splay(int x){
36         relax(x);
37         while (!isroot(x)){
38             if (isroot(fa[x])) rotate(x);
39             else if (which(fa[x])==which(x)) rotate(fa[x]),rotate(x);
40             else rotate(x),rotate(x);
41         }
42         updata(x);
43     }
44     void access(int x){for (int p=0;x;x=fa[x]) splay(x),son[x][1]=p,p=x;}
45     void make_root(int x){access(x),splay(x),addtag_rev(x);}
46     void connect(int u,int v){make_root(u),fa[u]=v;}
47     int query_sum(int u,int v){make_root(u),access(v),splay(v);return sum[v];}
48     int find_left(int x){for (pushdown(x);son[x][0];x=son[x][0],pushdown(x));return x;}
49     bool query_con(int u,int v){make_root(u),access(v),splay(v);return find_left(v)==u;}
50     void modify(int x,int v){val[x]=sum[x]=v,splay(x);}
51 }T;
52 int main(){
53     read(n);
54     for (int i=1;i<=n;i++) read(x),T.modify(i,x);
55     for (read(q);q;q--){
56         scanf("%s",op+1),read(x),read(y);
57         if (op[1]=='b'){
58             if (T.query_con(x,y)) puts("no");
59             else T.connect(x,y),puts("yes");
60         }
61         else if (op[1]=='p') T.modify(x,y);
62         else if (op[1]=='e'){
63             if (T.query_con(x,y)) printf("%d\n",T.query_sum(x,y));
64             else puts("impossible");    
65         }
66     }
67     return 0;
68 }
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息