【题意】给定n个点的树,从无到有加边,过程中动态询问当前图某条边两端连通点数的乘积,n<=10^5。

【算法】线段树合并+并查集  (||LCT(LCT维护子树信息 LCT维护子树信息(+启发式合并))——嗷嗷待补)

【题解】先将所有边离线加入计算dfs序(套路,强制固定原树形态)

对于一条边(u,v),fa[v]=u,ans=size[v]*(sz-size[v]),size[v]是v子树大小,sz是u-v所在连通块的大小(该边在查询前一定已经加入)

对每个点维护一棵dfs序线段树表示哪些点在此连通块,初始状态对自己的dfs序+1,那么询问子树size就是区间求和(子树是dfs序上的一段区间)。

用并查集维护连通块,强制连通块的根是深度最小的点的线段树,加边就是线段树合并了。

(当所有单链不一致的时候,merge不用做叶子结点处理。)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn=;
int n,m,first[maxn],root[maxn],q[maxn][],d[maxn],g[maxn],tot,cnt,dfsnum,fa[maxn];
char s[];
struct edge{int v,from;}e[maxn*];
struct tree{int l,r,sum;}t[maxn*];
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
void ins(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
void dfs(int x,int fa){
d[x]=++dfsnum;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){
dfs(e[i].v,x);
}
g[x]=dfsnum;
}
void insert(int l,int r,int &x,int y){
if(!x)x=++cnt;t[x].sum++;
if(l==r)return;
int mid=(l+r)>>;
if(y<=mid)insert(l,mid,t[x].l,y);
else insert(mid+,r,t[x].r,y);
}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int merge(int x,int y){
if(!x||!y)return x^y;
t[x].l=merge(t[x].l,t[y].l);
t[x].r=merge(t[x].r,t[y].r);
t[x].sum=t[t[x].l].sum+t[t[x].r].sum;
return x;
}
int ask(int l,int r,int k,int left,int right){
if(left<=l&&r<=right)return t[k].sum;
int mid=(l+r)>>,sum=;
if(left<=mid)sum=ask(l,mid,t[k].l,left,right);
if(right>mid)sum+=ask(mid+,r,t[k].r,left,right);
return sum;
}
int main(){
n=read();m=read();
for(int i=;i<=m;i++){
scanf("%s",s);
if(s[]=='A'){
q[i][]=;q[i][]=read();q[i][]=read();
ins(q[i][],q[i][]);ins(q[i][],q[i][]);
}
else{
q[i][]=;q[i][]=read();q[i][]=read();
}
}
for(int i=;i<=n;i++)if(!d[i])dfs(i,);
for(int i=;i<=n;i++)insert(,n,root[i],d[i]);
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=m;i++){
if(d[q[i][]]>d[q[i][]])swap(q[i][],q[i][]);//1fa 2son
if(!q[i][]){
root[find(q[i][])]=merge(root[find(q[i][])],root[find(q[i][])]);
fa[fa[q[i][]]]=fa[q[i][]];//zhi xiang
}
else{
int sonsize=ask(,n,root[find(q[i][])],d[q[i][]],g[q[i][]]);
int fasize=t[root[find(q[i][])]].sum;
printf("%d\n",sonsize*(fasize-sonsize));
}
}
return ;
}

【BZOJ】4530: [Bjoi2014]大融合的更多相关文章

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

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

  2. BZOJ.4530.[BJOI2014]大融合(LCT)

    题目链接 BZOJ 洛谷 详见这 很明显题目是要求去掉一条边后两边子树sz[]的乘积. LCT维护的是链的信息,那么子树呢? 我们用s_i[x]来记录轻边连向x的子树的和(记作虚儿子),那么sum[x ...

  3. bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...

  4. 【刷题】BZOJ 4530 [Bjoi2014]大融合

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

  5. bzoj 4530: [Bjoi2014]大融合【LCT】

    新姿势,一般来讲LCT只能维护splay重边里的数据,而这里要求维护整颗子树的size 多维护一个sq表示当前点轻儿子的size和,si表示包括轻重边的整颗子树的大小 然后需要改sq的地方是link和 ...

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

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

  7. BZOJ_4530_[Bjoi2014]大融合_LCT

    BZOJ_4530_[Bjoi2014]大融合_LCT Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个 ...

  8. P4219 [BJOI2014]大融合(LCT)

    P4219 [BJOI2014]大融合 对于每个询问$(u,v)$所求的是 ($u$的虚边子树大小+1)*($v$的虚边子树大小+1) 于是我们再开个$si[i]$数组表示$i$的虚边子树大小,维护一 ...

  9. 洛谷 P4219 [BJOI2014]大融合 解题报告

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

随机推荐

  1. 二叉搜索树(BST)---python实现

    github:代码实现 本文算法均使用python3实现 1. 二叉搜索树定义   二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree).   二叉搜 ...

  2. iOS- 如何将非ARC的项目转换成ARC项目(实战)

    1.前言   因为公司有个国外餐饮系统,编程开发了3-4年,之前用的都是非ARC,开发到今年,第一批迭代开发的人员早已不见,目前发现了有许多的内存泄露之类的,系统没有自动释放该释放的内存.一旦app长 ...

  3. lol人物模型提取(七)

      9月13号我就把上了贴图的模型文件发了过去,到9月18号他们那的颜色就上好了,一个叫"3d打印旗舰店"的人加了我微信并拍了几张照片发了给我,效果图如下:   第一眼看上去我还是 ...

  4. LR脚本编写时的几个小技巧

    参数化空值 如上图所示,当参数化时某个值需要为空值(非空格),直接在参数化文件中空一行/格即可,虽然Parameter List界面上没有显示空的那一行,但并不影响取值. 手工日志跟踪 lr_set_ ...

  5. 【Linux】- Ubuntu安装nginx

    安装 执行命令: sudo apt-get install nginx 执行如图: 防火墙设置 查看防火墙状态: sudo ufw status 查看可以穿过防火墙的应用列表: sudo ufw ap ...

  6. 【Docker 教程】- Docker 架构

    1.Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器. 2.Docker 容器通过 Docker 镜像来创建. 3.容器与镜像的关系类似于面向对象编程 ...

  7. 添加路由时啥时候是dev啥时候是gw

    A qumu ethA1 B 宿主机 ethA2  ethC2 C 树莓派 ethC1 在A和C中都是直接sudo route add default dev ethA1/ethC1 这样做是有问题的 ...

  8. 【bzoj3529】[Sdoi2014]数表 莫比乌斯反演+离线+树状数组

    题目描述 有一张n×m的数表,其第i行第j列(1 <= i <= n ,1 <= j <= m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. ...

  9. 整合常用功能的JS小组件库-v1.0

    function Alex() { //给予video.js的页面滚动到视频元素范围内自动播放/出范围暂停播放-----01 this.video_autoplay = function (box) ...

  10. 【题解】SCOI2006萌萌哒

    看到这题,首先想到\(n^{2}\)的暴力,就是用并查集暴力合并两个相等的点.但由于这样会导致反复地访问同一个操作,显然是不能够的.于是我们可以联想这题的特殊性质,就是互相连变的点都是一段一段的区间. ...