zoukankan      html  css  js  c++  java
  • P4219 [BJOI2014]大融合 ( LCT维护虚实子树size )

    题目描述

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

    例如,在上图中,现在一共有了555条边。其中,(3,8)(3,8)(3,8)这条边的负载是666,因 为有六条简单路径2−3−82-3-8238,2−3−8−72-3-8-72387,3−8,3−8−73-8,3-8-738,387,4−3−84-3-8438,4−3−8−74-3-8-74387路过了(3,8)(3,8)(3,8)。

    现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的 询问。

    输入输出格式

    输入格式:

     

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

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

    • A x y 表示在 xxx和 yyy 之间连一条边。保证之前 xxx 和 yyy是不联通的。
    • Q x y表示询问 (x,y)(x,y)(x,y) 这条边上的负载。保证 xxx 和 yyy 之间有一条边。

     

    输出格式:

     

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

     

    输入输出样例

    输入样例#1: 复制
    8 6
    A 2 3
    A 3 4
    A 3 8
    A 8 7
    A 6 5
    Q 3 8
    输出样例#1: 复制
    6

    说明

    对于所有数据,1≤N,Q≤1051≤N,Q≤10^51N,Q105

    SOLUTION:

    lct在维护链的同时维护一个虚子树的信息

     

    CODE:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #define R register int
     4 #define I inline void
     5 const int N=100009;
     6 int f[N],c[N][2],si[N],s[N];
     7 bool r[N];
     8 #define lc c[x][0]
     9 #define rc c[x][1]
    10 inline bool nroot(R x){return c[f[x]][0]==x||c[f[x]][1]==x;}
    11 I pushup(R x){
    12     s[x]=s[lc]+s[rc]+si[x]+1;
    13 }
    14 I pushdown(R x){
    15     if(r[x]){
    16         R t=lc;lc=rc;rc=t;
    17         r[lc]^=1;r[rc]^=1;r[x]=0;
    18     }
    19 }
    20 I pushall(R x){
    21     if(nroot(x))pushall(f[x]);
    22     pushdown(x);
    23 }
    24 I rotate(R x){
    25     R y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k];
    26     if(nroot(y))c[z][c[z][1]==y]=x;c[x][!k]=y;c[y][k]=w;
    27     f[w]=y;f[y]=x;f[x]=z;
    28     pushup(y);
    29 }
    30 I splay(R x){//请忽略这个spaly
    31     pushall(x);
    32     while(nroot(x))rotate(x);
    33     pushup(x);
    34 }
    35 I access(R x){
    36     for(R y=0;x;x=f[y=x]){
    37         splay(x);
    38         si[x]+=s[rc];
    39         si[x]-=s[rc=y];
    40         //pushup(x);试着去掉,发现对答案无影响
    41     }
    42 }
    43 I makeroot(R x){
    44     access(x);splay(x);
    45     r[x]^=1;
    46 }
    47 I split(R x,R y){
    48     makeroot(x);
    49     access(y);splay(y);
    50 }
    51 I link(R x,R y){
    52     split(x,y);
    53     si[f[x]=y]+=s[x];
    54     pushup(y);
    55 }//LCT模板到此结束
    56 #define G ch=getchar()
    57 #define gc G;while(ch<'-')G
    58 #define in(z) gc;z=ch&15;G;while(ch>'-')z*=10,z+=ch&15,G;
    59 int main(){
    60     register char ch;
    61     register bool fl;
    62     R n,q,u,v;
    63     in(n);in(q);
    64     for(R i=1;i<=n;++i)s[i]=1;
    65     while(q--){
    66         gc;fl=ch=='A';in(u);in(v);
    67         if(fl)link(u,v);
    68         else{
    69            makeroot(u); access(v);
    70            ///题目保证x和y右边,所以我们把u换位根后,在access
    71            ///  u和v一定是相邻的
    72                printf("%lld
    ",(long long)(si[u]+1)*(si[v]+1));//可以换成上面提到的另一种
    73         }
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    JQuery+ajax数据加载..........
    JQuery文本框验证
    将SqlDataReader 数据集转化为datatbale ,在将datatable 转化为iList
    DataSet转化为DataTable
    Case 降序升序排列
    Sql case
    sql STUFF 分组
    全/反选
    【面试题034】丑数
    【面试题033】把数组排成最小的数
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11162832.html
Copyright © 2011-2022 走看看