• 【BZOJ 1180】 (LCT)


    1180: [CROATIAN2009]OTOCI

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

    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

    Sample Output

    4
    impossible
    yes
    6
    yes
    yes
    15
    yes
    15
    16

    HINT

    Source

    【分析】

      LCT裸题。。

      没有cut操作。。

      嗯。。。还是要调试啊。。。

      注意LCT是维护链的,,询问路径对LCT来说就是小菜一碟。。

      不过之前维护子树的那题用LCT变成路径维护的感觉很强啊。。

      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
    ");
    140             else
    141             {
    142                 LCT.split(x,y);
    143                 printf("%d
    ",tr[y].sm);
    144             }
    145         }
    146         else if(s[0]=='b')
    147         {
    148             if(!LCT.cn(x,y)) {printf("yes
    ");LCT.link(x,y);}
    149             else printf("no
    ");
    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:31

  • 相关阅读:
    selenium又一小坑 无法用XPATH直接获取属性值 需要使用.get_attribute(“href”)
    seleium 之 EC 的用法
    用筛选法求100以内的素数(筛选法!!!)
    gets scanf getchar的用法
    P5728 【深基5.例5】旗鼓相当的对手
    访问那个地址上的变量 *
    素数表
    求素数
    求符合给定条件的整数集(c语言mooc 6.0 )
    C#理论学习
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6773073.html
Copyright © 2020-2023  润新知