Description

小强要在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)。
现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的
询问。

Input

第一行包含两个整数N,Q,表示星球的数量和操作的数量。星球从1开始编号。
接下来的Q行,每行是如下两种格式之一:
A x y 表示在x和y之间连一条边。保证之前x和y是不联通的。
Q x y 表示询问(x,y)这条边上的负载。保证x和y之间有一条边。
1≤N,Q≤100000

Output

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

Sample Input

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

Sample Output

6

HINT

 

Source

 
数据结构简单题嘛,我们发现答案为min(siz[x],siz[y])*(SIZE[x]-min(siz[x],siz[y])),其中siz[x]表示以x为根子树的大小,SIZE[x]表示x所在树的大小。
添加一条边x-y时启发式合并一下,设x为SIZE较小的那一个,将x所在的树暴力重构,用动态树将y到其根的路径上所有siz值加上SIZE[x]。
时间复杂度仍为O(MlogN)。
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define lc ch[x][0]
#define rc ch[x][1]
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,1,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=0,f=1;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
return x*f;
}
typedef long long ll;
const int maxn=100010;
int n,m,pa[maxn],siz[maxn],ch[maxn][2],s[maxn],add[maxn],pre[maxn],fa[maxn];
int findset(int x) {return x==pa[x]?x:pa[x]=findset(pa[x]);}
void Add(int x,int v) {if(x) add[x]+=v,s[x]+=v;}
void pushdown(int x) {
if(add[x]) Add(lc,add[x]),Add(rc,add[x]),add[x]=0;
}
void rotate(int x) {
int y=pre[x],z=pre[y],d=ch[y][0]==x;
ch[y][d^1]=ch[x][d];pre[ch[x][d]]=y;
ch[z][ch[z][1]==y]=x;pre[x]=z;
ch[x][d]=y;pre[y]=x;
}
int ST[maxn],top;
void splay(int x) {
for(int i=x;i;i=pre[i]) ST[++top]=i;
if(top!=1) fa[x]=fa[ST[top]],fa[ST[top]]=0;
while(top) pushdown(ST[top--]);
while(pre[x]) rotate(x);
}
void access(int x) {
for(int y=0;x;x=fa[x]) {
splay(x);pre[ch[x][1]]=0;fa[ch[x][1]]=x;
ch[x][1]=y;pre[y]=x;y=x;
}
}
int first[maxn],next[maxn<<1],to[maxn<<1],e;
void AddEdge(int u,int v) {
to[++e]=v;next[e]=first[u];first[u]=e;
to[++e]=u;next[e]=first[v];first[v]=e;
}
void dfs(int x,int f) {
fa[x]=f;lc=rc=0;pre[x]=0;s[x]=1;
ren if(to[i]!=f) dfs(to[i],x),s[x]+=s[to[i]];
}
void link(int x,int y) {
AddEdge(x,y);
int f1=findset(x),f2=findset(y);
if(siz[f1]>siz[f2]) swap(f1,f2),swap(x,y);
pa[f1]=f2;siz[f2]+=siz[f1];
access(y);splay(y);Add(y,siz[f1]);
dfs(x,y);
}
int query(int x) {splay(x);return s[x];}
int main() {
n=read();m=read();
rep(i,1,n) siz[i]=s[i]=1,pa[i]=i;
rep(i,1,m) {
char c=Getchar();
while(!isalpha(c)) c=Getchar();
if(c=='A') link(read(),read());
else {
int x=read(),y=read();
int sum=min(query(y),query(x));
printf("%lld\n",(ll)sum*(siz[findset(x)]-sum));
}
}
return 0;
}

  

BZOJ4530: [Bjoi2014]大融合的更多相关文章

  1. [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并

    [BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...

  2. [bzoj4530][Bjoi2014]大融合_LCT

    大融合 bzoj-4530 Bjoi-2014 题目大意:n个点,m个操作,支持:两点连边:查询两点负载:负载.边(x,y)的负载就是将(x,y)这条边断掉后能和x联通的点的数量乘以能和y联通的点的数 ...

  3. BZOJ4530 BJOI2014大融合(线段树合并+并查集+dfs序)

    易知所求的是两棵子树大小的乘积.先建出最后所得到的树,求出dfs序和子树大小.之后考虑如何在动态加边过程中维护子树大小.这个可以用树剖比较简单的实现,但还有一种更快更优美的做法就是线段树合并.对每个点 ...

  4. BZOJ4530[Bjoi2014]大融合——LCT维护子树信息

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

  5. 2019.01.14 bzoj4530: [Bjoi2014]大融合(线段树合并)

    传送门 线段树合并菜题. 题意简述:nnn个点,支持连边以及查询一个点所在连通块中经过这个点的路径条数,保证这张图时刻为森林. 思路: 先建出所有操作完之后的树统计出dfsdfsdfs序 注意有可能是 ...

  6. [BZOJ4530][Bjoi2014]大融合(LCT)

    传送门 大佬们似乎都是用树剖+并查集优雅地A了此题 然后我太弱了,只能打打LCT的板子 虽然的确可以挺无脑的A掉…… 不过至少这题教了我该怎么维护LCT上虚子树的信息,具体看这里 首先,答案很明显是断 ...

  7. BZOJ4530:[BJOI2014]大融合(LCT)

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

  8. bzoj4530 [Bjoi2014]大融合 子树信息 LCT

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4530/ 题解 想要求出一条边的负载那么就是要求出一个点为根的时候的另一个点的子树大小. 又因为 ...

  9. BZOJ:4530: [Bjoi2014]大融合

    4530: [Bjoi2014]大融合 拿这题作为lct子树查询的练手.本来以为这会是一个大知识点,结果好像只是一个小技巧? 多维护一个虚边连接着的子树大小即可. #include<cstdio ...

随机推荐

  1. python列表分组的技巧

    今天项目上需要到的. 如,将并行部署的机器分批次. 一次十台机器,如果分3次并行部署,则第一次123,第二次456,第三次789,第四次10. #coding=utf-8 a=[1,2,3,4,5,6 ...

  2. makefile基础(GNU)

    makefile的核心 targets : prerequisites ; commands...   //不分行的情况 targets : prerequisites                 ...

  3. sublime text 全局搜索

    Ctrl+Shift+F Mac下是commadn+Shift+F 在下面Find中填入需要搜索的关键字 点击find

  4. C++Primer快速浏览笔记-复合类型

    C++Primer2.3节介绍了两种复合类型:引用和指针 1.引用 引用并非对象,它只是为一个已经存在的对象所起的别名. 一旦初始化完成,引用将和它的初始值对象一直绑定在一起,不能重新绑定到另一个对象 ...

  5. [荐] jQuery取得select选择的文本与值

    csdn:http://blog.csdn.net/tiemufeng1122/article/details/44154571 jquery获取select选择的文本与值获取select :获取se ...

  6. Java api

    StringBuilder.charAt(int index); StringBuilder.deleteCharAt(int index); StringBuilder.setCharAt(int ...

  7. BurpSuite拦截HTTPS请求

    1.设置好浏览器代理 2. 3.请求https站点(比如https://www.baidu.com),以火狐浏览器例子: 4. 这一步主要是为了显示[我已充分了解可能的风险],如果有,就不用做以上步骤 ...

  8. ArrayList和LinkedList的几种循环遍历方式及性能对比分析

    最新最准确内容建议直接访问原文:ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性 ...

  9. Angular JS学习之表达式

    1.Angular JS使用表达式把数据绑定到HTML: 2.Angular JS表达式写在双大括号中:{{expression}} **Angular JS表达式把数据绑定到HTML,这与ng-bi ...

  10. jQuery实现等比例缩放大图片

      在布局页面时,有时会遇到大图片将页面容器“撑破”的情况,尤其是加载外链图片(通常是通过采集的外站的图片).那么本文将为您讲述使用jQuery如何按比例缩放大图片,让大图片自适应页面布局. 通常我们 ...