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
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
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 ",T.query_sum(x,y)); 64 else puts("impossible"); 65 } 66 } 67 return 0; 68 }