zoukankan      html  css  js  c++  java
  • 大融合

    小强要在 $N$ 个孤立的星球上建立起一套通信系统。这套通信系统就是连接 $N$ 个点的一个树。这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够联通的树上路过它的简单路径的数量。
    例如,在上图中,现在一共有五条边。其中,$(3,8)$ 这条边的负载是 $6$,因为有六条简单路径 $2-3-8, 2-3-8-7, 3-8, 3-8-7, 4-3-8, 4-3-8-7$ 路过了 $(3,8)$。
    现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的询问。

    Solution

    题目求的是一条边两侧子树大小之积。支持插边。

    那么可以考虑lct。

    有个问题:lct不能维护子树信息。

    那么我们可以对于一个点,把实儿子和虚儿子分开维护,还有一个总的信息。

    总信息=实儿子的总信息+虚儿子的信息+本身的信息。

    要改的只有link和access。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #define maxn 100005
     8 using namespace std;
     9 int n,q,t1,t2;
    10 struct node{
    11     int f,ch[2],sum,sx,sy;//sum ×ÜºÍ sx ʵ×ÓÊ÷ sy Ðé×ÓÊ÷ 
    12     int re;
    13 }tr[maxn]; 
    14 void wh(int x){
    15     int ls=tr[x].ch[0],rs=tr[x].ch[1];
    16     tr[x].sum=tr[ls].sum+tr[rs].sum+tr[x].sy+1;
    17 }
    18 int zh[maxn],top;
    19 void upv(int x){
    20     if(!x)return;
    21     tr[x].re^=1;
    22     swap(tr[x].ch[0],tr[x].ch[1]);
    23 }
    24 void down(int x){
    25     if(tr[x].re){
    26         upv(tr[x].ch[0]);upv(tr[x].ch[1]);
    27         tr[x].re=0;
    28     }
    29 }
    30 int get(int x){
    31     return tr[tr[x].f].ch[1]==x;
    32 }
    33 bool isroot(int x){
    34     return tr[tr[x].f].ch[0]!=x&&tr[tr[x].f].ch[1]!=x;
    35 }
    36 
    37 void rotate(int x){
    38     int y=tr[x].f,z=tr[y].f;
    39     int wx=get(x),wy=get(y);
    40     if(!isroot(y))tr[z].ch[wy]=x;tr[x].f=z;
    41     tr[y].ch[wx]=tr[x].ch[wx^1];tr[tr[x].ch[wx^1]].f=y;
    42     tr[x].ch[wx^1]=y;tr[y].f=x;
    43     wh(y);wh(x);
    44 }
    45 void splay(int x){
    46     int y=x;top=0;
    47     for(;!isroot(y);y=tr[y].f)zh[++top]=y;zh[++top]=y;
    48     while(top)down(zh[top--]);
    49     while(!isroot(x)){
    50         y=tr[x].f;
    51         if(!isroot(y))rotate(get(y)==get(x)?y:x);
    52         rotate(x);    
    53     }
    54 }
    55 void access(int x){
    56     for(int y=0;x;y=x,x=tr[x].f){
    57         splay(x);
    58         tr[x].sy+=tr[tr[x].ch[1]].sum;
    59         tr[x].ch[1]=y;
    60         tr[x].sy-=tr[y].sum;
    61         wh(x);
    62     }
    63 }
    64 void makeroot(int x){
    65     access(x);splay(x);
    66     upv(x);wh(x);
    67 }
    68 void link(int x,int y){
    69     makeroot(x);makeroot(y);
    70     tr[x].f=y;
    71     tr[y].sy+=tr[x].sum;wh(y);
    72 }
    73 void split(int x,int y){
    74     makeroot(x);
    75     access(y);splay(y);
    76 }
    77 long long ask(int x,int y){
    78     split(x,y);
    79     int s1=tr[x].sum,s2=tr[y].sum-s1;
    80     
    81     return 1LL*s1*s2;
    82 }
    83 int main()
    84 {
    85     cin>>n>>q;
    86     for(int i=1;i<=n;i++)tr[i].sum=1;
    87     while(q--){
    88         char ch;scanf(" %c",&ch);
    89         scanf("%d%d",&t1,&t2);
    90         if(ch=='A')link(t1,t2);
    91         else printf("%lld
    ",ask(t1,t2));
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    微信小程序 添加卡券至微信卡券
    微信小程序 引入第三方字体
    小程序 生成条形码barcode.js
    Pycharm编辑器功能之自动导入模块
    Cannot open include file: 'libxml/xpath.h': No such file or directory
    怎么在32位windows系统上搭建爬虫框架scrapy?
    python2.7安装Twisted报Microsoft Visual C++9.0 required
    在windows下搭建爬虫框架,安装pywin32时出错?
    python如何通过pymongo连接到mongodb?
    python2.7.12自带pip吗?
  • 原文地址:https://www.cnblogs.com/liankewei/p/10657087.html
Copyright © 2011-2022 走看看