bzoj2843 极地旅行社 LCT

Posted Kaiser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2843 极地旅行社 LCT相关的知识,希望对你有一定的参考价值。

极地旅行社

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1010  Solved: 597
[Submit][Status][Discuss]

Description

不久之前,Mirko建立了一个旅行社,名叫“极地之梦”。这家旅行社在北极附近购买了N座冰岛,并且提供观光服
务。当地最受欢迎的当然是帝企鹅了,这些小家伙经常成群结队的游走在各个冰岛之间。Mirko的旅行社遭受一次
重大打击,以至于观光游轮已经不划算了。旅行社将在冰岛之间建造大桥,并用观光巴士来运载游客。Mirko希望
开发一个电脑程序来管理这些大桥的建造过程,以免有不可预料的错误发生。这些冰岛从1到N标号。一开始时这些
岛屿没有大桥连接,并且所有岛上的帝企鹅数量都是知道的。每座岛上的企鹅数量虽然会有所改变,但是始终在[0
, 1000]之间。你的程序需要处理以下三种命令:
1."bridge A B"——在A与B之间建立一座大桥(A与B是不同的岛屿)。由于经费限制,这项命令被接受,当且仅当
A与B不联通。若这项命令被接受,你的程序需要输出"yes",之
后会建造这座大桥。否则,你的程序需要输出"no"。
2."penguins A X"——根据可靠消息,岛屿A此时的帝企鹅数量变为X。这项命令只是用来提供信息的,你的程序不
需要回应。
3."excursion A B"——一个旅行团希望从A出发到B。若A与B连通,你的程序需要输出这个旅行团一路上所能看到的
帝企鹅数量(包括起点A与终点B),若不联通,你的程序需要输出"impossible"。

Input

第一行一个正整数N,表示冰岛的数量。
第二行N个范围[0, 1000]的整数,为每座岛屿初始的帝企鹅数量。
第三行一个正整数M,表示命令的数量。接下来M行即命令,为题目描述所示。
1<=N<=30000,1<=M<=100000

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

 

 题解:模板题
  1 #include<cstring>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstdio>
  6 
  7 #define N 30007
  8 using namespace std;
  9 inline int read()
 10 {
 11     int x=0,f=1;char ch=getchar();
 12     while(ch>9||ch<0){if (ch==-) f=-1;ch=getchar();}
 13     while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
 14     return x*f;
 15 }
 16 
 17 int n,m;
 18 int sum[N],num[N],rev[N];
 19 int c[N][2],fa[N],st[N];
 20 
 21 void update(int p)
 22 {
 23     int l=c[p][0],r=c[p][1];
 24     sum[p]=sum[l]+sum[r]+num[p];
 25 }
 26 void pushdown(int p)
 27 {
 28     int l=c[p][0],r=c[p][1];
 29     if (rev[p])
 30     {
 31         rev[p]^=1,rev[l]^=1,rev[r]^=1;
 32         swap(c[p][0],c[p][1]);
 33     }
 34 }
 35 inline bool isroot(int x)
 36 {
 37      return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
 38  }
 39 void rotate(int x)
 40 {
 41     int y=fa[x],z=fa[y],l,r;
 42     if (c[y][0]==x) l=0;else l=1;r=l^1;
 43     if (!isroot(y))
 44     {
 45         if (c[z][0]==y) c[z][0]=x;
 46         else c[z][1]=x;
 47     }
 48     fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
 49     c[y][l]=c[x][r],c[x][r]=y;
 50     update(y),update(x);
 51 }
 52 void splay(int x)
 53 {
 54     int top=0;st[++top]=x;
 55     for (int i=x;!isroot(i);i=fa[i])
 56         st[++top]=fa[i];
 57     for (int i=top;i>=1;i--)
 58         pushdown(st[i]);
 59     while(!isroot(x))
 60     {
 61         int y=fa[x],z=fa[y];
 62         if (!isroot(y))
 63         {
 64             if (c[y][0]==x^c[z][0]==y) rotate(x);
 65             else rotate(y);
 66         }
 67         rotate(x);
 68     }
 69 }
 70 void access(int x)
 71 {
 72     int t=0;
 73     while(x)
 74     {
 75         splay(x);
 76         c[x][1]=t;
 77         update(x);
 78         t=x,x=fa[x];
 79     }
 80 }
 81 void makeroot(int x)
 82 {
 83     access(x);
 84     splay(x);
 85     rev[x]^=1;
 86 }
 87 void link(int x,int y)
 88 {
 89     makeroot(x);
 90     fa[x]=y;
 91     splay(x);
 92 }
 93 int find(int x)
 94 {
 95     access(x),splay(x);
 96     int y=x;
 97     while(c[y][0]) y=c[y][0];
 98     return y;
 99 }
100 void cut(int x,int y)
101 {
102     makeroot(x);
103     access(y);
104     splay(y);
105     fa[x]=c[y][0]=0;
106 }
107 int main()
108 {    
109     freopen("fzy.in","r",stdin);
110     freopen("fzy.out","w",stdout);
111 
112     n=read();
113     for (int i=1;i<=n;i++)
114         num[i]=sum[i]=read();
115     m=read();
116     while(m--)
117     {
118         char ch[20];scanf("%s",ch);
119         if (ch[0]==b)
120         {
121             int u=read(),v=read();
122             if (find(u)!=find(v)) printf("yes\n"),link(u,v);
123             else printf("no\n");
124         }
125         else if (ch[0]==p)
126         {
127             int x=read(),y=read();
128             num[x]=y;
129             splay(x);
130         }
131         else
132         {
133             int u=read(),v=read();
134             if (find(u)!=find(v))
135             {
136                 printf("impossible\n");
137                 continue;
138             }
139             makeroot(u),access(v),splay(v);
140             printf("%d\n",sum[v]);
141         }
142     }
143 }

 

以上是关于bzoj2843 极地旅行社 LCT的主要内容,如果未能解决你的问题,请参考以下文章

bzoj2843极地旅行社 LCT

bzoj2843极地旅行社题解

BZOJ2843: 极地旅行社

BZOJ2843极地旅行社(Link-Cut Tree)

BZOJ 2843极地旅行社

bzoj 2843: 极地旅行社