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)。
  1. #include<cstdio>
  2. #include<cctype>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define lc ch[x][0]
  6. #define rc ch[x][1]
  7. #define rep(i,s,t) for(int i=s;i<=t;i++)
  8. #define dwn(i,s,t) for(int i=s;i>=t;i--)
  9. #define ren for(int i=first[x];i;i=next[i])
  10. using namespace std;
  11. const int BufferSize=1<<16;
  12. char buffer[BufferSize],*head,*tail;
  13. inline char Getchar() {
  14. if(head==tail) {
  15. int l=fread(buffer,1,BufferSize,stdin);
  16. tail=(head=buffer)+l;
  17. }
  18. return *head++;
  19. }
  20. inline int read() {
  21. int x=0,f=1;char c=Getchar();
  22. for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
  23. for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
  24. return x*f;
  25. }
  26. typedef long long ll;
  27. const int maxn=100010;
  28. int n,m,pa[maxn],siz[maxn],ch[maxn][2],s[maxn],add[maxn],pre[maxn],fa[maxn];
  29. int findset(int x) {return x==pa[x]?x:pa[x]=findset(pa[x]);}
  30. void Add(int x,int v) {if(x) add[x]+=v,s[x]+=v;}
  31. void pushdown(int x) {
  32. if(add[x]) Add(lc,add[x]),Add(rc,add[x]),add[x]=0;
  33. }
  34. void rotate(int x) {
  35. int y=pre[x],z=pre[y],d=ch[y][0]==x;
  36. ch[y][d^1]=ch[x][d];pre[ch[x][d]]=y;
  37. ch[z][ch[z][1]==y]=x;pre[x]=z;
  38. ch[x][d]=y;pre[y]=x;
  39. }
  40. int ST[maxn],top;
  41. void splay(int x) {
  42. for(int i=x;i;i=pre[i]) ST[++top]=i;
  43. if(top!=1) fa[x]=fa[ST[top]],fa[ST[top]]=0;
  44. while(top) pushdown(ST[top--]);
  45. while(pre[x]) rotate(x);
  46. }
  47. void access(int x) {
  48. for(int y=0;x;x=fa[x]) {
  49. splay(x);pre[ch[x][1]]=0;fa[ch[x][1]]=x;
  50. ch[x][1]=y;pre[y]=x;y=x;
  51. }
  52. }
  53. int first[maxn],next[maxn<<1],to[maxn<<1],e;
  54. void AddEdge(int u,int v) {
  55. to[++e]=v;next[e]=first[u];first[u]=e;
  56. to[++e]=u;next[e]=first[v];first[v]=e;
  57. }
  58. void dfs(int x,int f) {
  59. fa[x]=f;lc=rc=0;pre[x]=0;s[x]=1;
  60. ren if(to[i]!=f) dfs(to[i],x),s[x]+=s[to[i]];
  61. }
  62. void link(int x,int y) {
  63. AddEdge(x,y);
  64. int f1=findset(x),f2=findset(y);
  65. if(siz[f1]>siz[f2]) swap(f1,f2),swap(x,y);
  66. pa[f1]=f2;siz[f2]+=siz[f1];
  67. access(y);splay(y);Add(y,siz[f1]);
  68. dfs(x,y);
  69. }
  70. int query(int x) {splay(x);return s[x];}
  71. int main() {
  72. n=read();m=read();
  73. rep(i,1,n) siz[i]=s[i]=1,pa[i]=i;
  74. rep(i,1,m) {
  75. char c=Getchar();
  76. while(!isalpha(c)) c=Getchar();
  77. if(c=='A') link(read(),read());
  78. else {
  79. int x=read(),y=read();
  80. int sum=min(query(y),query(x));
  81. printf("%lld\n",(ll)sum*(siz[findset(x)]-sum));
  82. }
  83. }
  84. return 0;
  85. }

  

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. 【openGL】关于画点

    #include "stdafx.h" #include <GL/glut.h> #include <stdlib.h> #include <math ...

  2. golang time and duration

    package mainimport "fmt"import "time"func main() { p := fmt.Println // We'll sta ...

  3. h264 profile & level

    转自:http://blog.csdn.net/sphone89/article/details/17492433 H.264 Profiles H.264有四种profile,每个profile支持 ...

  4. MyBatis传入参数与parameterType

    参考:http://openwares.net/database/mybatis_parametertype.html Mybatis的Mapper文件中的select.insert.update.d ...

  5. Database.com SOQL and SOSL Reference

    如下是关于 SOQ L与 SOSL 的相关链接: http://docs.database.com/dbcom/en-us/db_sosl_soql/sforce_api_calls_soql.htm ...

  6. PopupWindow响应返回键的问题

    假设情景是这样的:在一个Activity中弹出一个PopupWindow,要求在按返回键时关闭该PopupWindow. 如果该PopupWindow是无焦点的(默认情况),那么可以在Activity ...

  7. JS获得鼠标位置

    <body> <script> function mouseMove(ev) { ev = ev || window.event; var mousePos = mouseCo ...

  8. Swift3.0语言教程替换子字符串

    Swift3.0语言教程替换子字符串 Swift3.0语言教程替换子字符串,替换子字符串其实就是将字符串中的子字符串删除,然后再进行添加.为了让这一繁琐的过程变的简单,NSString提供了替换子字符 ...

  9. 关于oracle ORA-28001的解决方法

    今天发现客户的机器上的系统登录不上了,并且提示如下情况: 发现原来Oracle11G的新特性所致, Oracle11G创建用户时缺省密码过期限制是180天(即6个月), 如果超过180天用户密码未做修 ...

  10. 学习 Message(5): 关于 TApplicationEvents.OnMessage 的第二个参数 可以屏蔽 TWebBrowser右键菜单:

    http://www.cnblogs.com/del/archive/2008/10/25/1319318.html TApplicationEvents.OnMessage 的第二个参数 Handl ...