zoukankan      html  css  js  c++  java
  • [lct] Luogu P4219 大融合

    题目描述

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

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

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

    输入输出格式

    输入格式:

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

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

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

    输出格式:

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

    输入输出样例

    输入样例#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≤10^51N,Q105

    题解

    • 对于lct一般都是维护链上的操作,那么怎么维护子树上的信息呢
    • 定义siz[x]表示x的所有虚儿子的子树大小和,size[x]表示x的所有虚儿子+实儿子+自己的子树大小和
    • 那么只要在虚实边变化的时候维护一下siz的大小,同时维护size就好了
    • 求x的子树大小,只要access(x),然后siz[x]+1就是答案了

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #define N 300010
     5 using namespace std;
     6 int n,m,f[N],ch[N][2],v[N],s[N],size[N],tag[N];
     7 int nroot(int x) { return ch[f[x]][0]==x||ch[f[x]][1]==x; }
     8 void pushup(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+s[x]+1; }
     9 void pushdown(int x) { if (tag[x]) swap(ch[x][0],ch[x][1]),tag[ch[x][0]]^=1,tag[ch[x][1]]^=1,tag[x]=0; }
    10 void work(int x) { if (nroot(x)) work(f[x]); pushdown(x); }
    11 void rotate(int x)
    12 {
    13     int y=f[x],z=f[y],k=ch[y][1]==x,w=ch[x][!k];
    14     if (nroot(y)) ch[z][ch[z][1]==y]=x;
    15     ch[x][!k]=y,ch[y][k]=w,f[y]=x,f[x]=z;
    16     if (w) f[w]=y;
    17     pushup(y);
    18 }
    19 void splay(int x) { work(x); while (nroot(x)) rotate(x); pushup(x); }
    20 void access(int x) { for (int y=0;x;x=f[y=x]) splay(x),s[x]+=size[ch[x][1]],s[x]-=size[ch[x][1]=y],pushup(x); }
    21 void makeroot(int x) { access(x),splay(x),tag[x]^=1; }
    22 void split(int x,int y) { makeroot(x),access(y),splay(y); }
    23 void link(int x,int y) { split(x,y);s[f[x]=y]+=size[x],pushup(y); }
    24 int main()
    25 {
    26     scanf("%d%d",&n,&m);
    27     for (int i=1;i<=n;i++) size[i]=i;
    28     for (int x,y;m;m--)
    29     {
    30         char ch=getchar(); while (ch!='A'&&ch!='Q') ch=getchar();
    31         scanf("%d%d",&x,&y);
    32         if (ch=='Q') split(x,y),printf("%lld
    ",(s[x]+1)*(s[y]+1)); else link(x,y);
    33     }
    34 }
  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11129335.html
Copyright © 2011-2022 走看看