zoukankan      html  css  js  c++  java
  • BZOJ4530 [BJOI2014]大融合(LCT)

    题目描述

    小强要在N个孤立的星球上建立起一套通信系统。这套通信系统就是连接N个点的一个树。 这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它的简单路径的数量。

    例如,在上图中,现在一共有了5条边。其中,(3,8)这条边的负载是6,因 为有六条简单路径2-3-8,2-3-8-7,3-8,3-8-7,4-3-8,4-3-8-7路过了(3,8)。 现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的 询问。

    输入格式

    第一行包含两个整数N,Q,表示星球的数量和操作的数量。星球从1开始编号。

    接下来的Q行,每行是如下两种格式之一:

    A x y 表示在x和y之间连一条边。保证之前x和y是不联通的。

    Q x y 表示询问(x,y)这条边上的负载。保证x和y之间有一条边。 1≤N,Q≤100000

    输出格式

    对每个查询操作,输出被查询的边的负载。

    样例一

    input

    8 6
    A 2 3
    A 3 4
    A 3 8
    A 8 7
    A 6 5
    Q 3 8

    output

      6


    解题思路:

    维护子树信息,建虚树嘛。

    pushup时将虚子树答案合并即可。

    然后在换儿子/父亲时更新虚子树信息。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 const int N=200000;
      9 struct trnt{
     10     int ch[2];
     11     int fa;
     12     int lzt;
     13     int wgt;
     14     int wgti;
     15     bool anc;
     16 }tr[N];
     17 int n,q;
     18 char cmd[10];
     19 bool whc(int spc)
     20 {
     21     return tr[tr[spc].fa].rs==spc;
     22 }
     23 void pushup(int spc)
     24 {
     25     tr[spc].wgt=tr[spc].wgti+1+tr[lll].wgt+tr[rrr].wgt;
     26     return ;
     27 }
     28 void trr(int spc)
     29 {
     30     if(!spc)
     31         return ;
     32     tr[spc].lzt^=1;
     33     std::swap(lll,rrr);
     34     return ;
     35 }
     36 void pushdown(int spc)
     37 {
     38     if(tr[spc].lzt)
     39     {
     40         trr(lll);
     41         trr(rrr);
     42         tr[spc].lzt=0;
     43     }
     44     return ;
     45 }
     46 void recal(int spc)
     47 {
     48     if(!tr[spc].anc)
     49         recal(tr[spc].fa);
     50     pushdown(spc);
     51     return ;
     52 }
     53 void rotate(int spc)
     54 {
     55     int f=tr[spc].fa;
     56     bool k=whc(spc);
     57     tr[f].ch[k]=tr[spc].ch[!k];
     58     tr[spc].ch[!k]=f;
     59     if(tr[f].anc)
     60     {
     61         tr[f].anc=0;
     62         tr[spc].anc=1;
     63     }else
     64         tr[tr[f].fa].ch[whc(f)]=spc;
     65     tr[spc].fa=tr[f].fa;
     66     tr[f].fa=spc;
     67     tr[tr[f].ch[k]].fa=f;
     68     pushup(f);
     69     pushup(spc);
     70     return ;
     71 }
     72 void splay(int spc)
     73 {
     74     recal(spc);
     75     while(!tr[spc].anc)
     76     {
     77         int f=tr[spc].fa;
     78         if(tr[f].anc)
     79         {
     80             rotate(spc);
     81             return ;
     82         }
     83         if(whc(spc)^whc(f))
     84             rotate(spc);
     85         else
     86             rotate(f);
     87         rotate(spc);
     88     }
     89     return ;
     90 }
     91 void access(int spc)
     92 {
     93     int lst=0;
     94     while(spc)
     95     {
     96         splay(spc);
     97         tr[spc].wgti-=tr[lst].wgt;
     98         tr[spc].wgti+=tr[rrr].wgt;
     99         tr[rrr].anc=true;
    100         tr[lst].anc=false;
    101         rrr=lst;
    102         pushup(spc);
    103         lst=spc;
    104         spc=tr[spc].fa;
    105     }
    106     return ;
    107 }
    108 void Mtr(int spc)
    109 {
    110     access(spc);
    111     splay(spc);
    112     trr(spc);
    113     return ;
    114 }
    115 void split(int x,int y)
    116 {
    117     Mtr(x);
    118     access(y);
    119     splay(y);
    120     return ;
    121 }
    122 void link(int x,int y)
    123 {
    124     split(x,y);
    125     tr[x].fa=y;
    126     tr[y].wgti+=tr[x].wgt;
    127     pushup(y);
    128     return ;
    129 }
    130 int main()
    131 {
    132     scanf("%d%d",&n,&q);
    133     for(int i=1;i<=n;i++)
    134         tr[i].anc=true;
    135     while(q--)
    136     {
    137         scanf("%s",cmd);
    138         if(cmd[0]=='A')
    139         {
    140             int x,y;
    141             scanf("%d%d",&x,&y);
    142             link(x,y);
    143         }else{
    144             int x,y;
    145             scanf("%d%d",&x,&y);
    146             split(x,y);
    147             long long ans=(long long)((long long)(tr[x].wgti+1)*(long long)(tr[y].wgti+1));
    148             printf("%lld
    ",ans);
    149         }
    150     }
    151     return 0;
    152 }
  • 相关阅读:
    he canvas has been tainted by cross-origin data and tainted canvases may not be exported
    Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
    HOW TO REPLACE ALL OCCURRENCES OF A CHARACTER IN A STD::STRING
    one or more multiply defined symbols found
    Std::map too few template arguments
    Always run a program in administrator mode in Windows 10
    JSON.parse 必须用双引号包起来
    jni4net使用小结
    Cannot generate C# proxy dll with JNI4NET tool, running batch file as trusted assembly?
    Java access to the Domino Objects, Part 1
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9639976.html
Copyright © 2011-2022 走看看