【BZOJ 1180】 (LCT)

1180: [CROATIAN2009]OTOCI

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

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。node

Input

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

Output

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

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

 

 

【分析】ui

  LCT裸題。。spa

  沒有cut操做。。調試

  嗯。。。仍是要調試啊。。。code

  注意LCT是維護鏈的,,詢問路徑對LCT來講就是小菜一碟。。blog

  不過以前維護子樹的那題用LCT變成路徑維護的感受很強啊。。ip

 

  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:31string

相關文章
相關標籤/搜索