• 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
    "),link(u,v);
    123             else printf("no
    ");
    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
    ");
    137                 continue;
    138             }
    139             makeroot(u),access(v),splay(v);
    140             printf("%d
    ",sum[v]);
    141         }
    142     }
    143 }
  • 相关阅读:
    C++出现 error: no match for 'operator==' (operand types are 'Person' and 'const Person')
    python三元运算符公式/出错怎么看
    我学函数遗漏的东西
    学习函数时一些没注意到的地方
    Python文件操作回顾
    我学习python没有记住的东西
    转载
    UE SC -kismetmathlibrary
    LineTrace跟Overlap开销
    UE4 插件无法读取常见错误
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8119491.html
Copyright © 2020-2023  润新知