当前位置: 首页 > news >正文

P10657 BZOJ4998 星球联盟

P10657 BZOJ4998 星球联盟

大意

动态维护边双连通分量的大小。

思路

由于是动态的维护边双,我们可以用 LCT 维护。

但是我们的 LCT 无法处理与环有关的问题,我们采用并查集协助维护。具体来说,我们用数组 \(f\) 来维护缩点,\(f[i]\) 就代表点 \(i\) 所属的边双连通的代表元。所有在涉及有关 LCT 操作的时候,我们的 \(fa(x)\) 都要写成 \(find(fa(x))\),这是一个易错点。

特别的,我们的连边函数发生了变化,如果不成环,那就无所谓,还是按照原来的方式,如果是成环了,那就直接提取 \(x \to y\) 的路径,通过递归暴力缩点,由于每个点只会被缩一次,所以均摊复杂度很低。

在暴力缩点的过程中,我们可以用一个数组记录缩点后该边双连通分量的大小,这样就可以知道联盟的大小了。

代码

#include<iostream>
using namespace std;#define lc(x) t[x].ch[0]
#define rc(x) t[x].ch[1]
#define fa(x) t[x].fa
const int MAXN = 2 * 1e5 + 5;
struct node{int ch[2], fa, sz;bool tag;
}t[MAXN];int f[MAXN], cnt[MAXN];int fd(int x){return (x == f[x]) ? x : f[x] = fd(f[x]);
}bool isroot(int x){int fx = fd(fa(x));return (lc(fx) != x) && (rc(fx) != x);
}void pushup(int x){t[x].sz = t[lc(x)].sz + t[rc(x)].sz + 1;
}void update(int x){if(!x) return;swap(lc(x), rc(x));t[x].tag ^= 1;
}void pushdown(int x){if(t[x].tag){update(lc(x));update(rc(x));t[x].tag = 0;}
}void rotate(int x){int y = fd(fa(x)), z = fd(fa(y));int k = (rc(y) == x);if(!isroot(y)){t[z].ch[rc(z) == y] = x;}fa(x) = z;t[y].ch[k] = t[x].ch[k ^ 1];if(t[x].ch[k ^ 1]){fa(t[x].ch[k ^ 1]) = y;}t[x].ch[k ^ 1] = y;fa(y) = x;
}void pushshell(int x){if(!isroot(x)){pushshell(fd(fa(x)));}pushdown(x);
}void splay(int x){x = fd(x);pushshell(x);while(!isroot(x)){int y = fd(fa(x)), z = fd(fa(y));if(!isroot(y)){(rc(y) == x) ^ (rc(z) == y) ? rotate(x) : rotate(y);}rotate(x);}
}void access(int x){for(int y = 0;x;y = x, x = fd(fa(x))){splay(x);rc(x) = y;}
}void makeroot(int x){x = fd(x);access(x);splay(x);update(x);
}void split(int x, int y){makeroot(x);access(y);splay(y);
}int fdrt(int x){access(x);splay(x);while(lc(x)){pushdown(x);x = lc(x);}splay(x);return x;
}void merge(int x, int rt){if(!x) return;f[fd(x)] = fd(rt);if(x != rt) cnt[rt] += cnt[x];merge(lc(x), rt);merge(rc(x), rt);lc(x) = rc(x) = 0;
}bool link(int x, int y){x = fd(x), y = fd(y);if(x == y) return true;if(fdrt(x) != fdrt(y)){makeroot(x);fa(x) = y;return false;}else{split(x, y);merge(lc(y), y);return true;}
}int main(){int n, m, p;scanf("%d %d %d", &n, &m, &p);for(int i = 1;i <= n;i ++){f[i] = i;cnt[i] = 1;}for(int i = 0;i < m;i ++){int u, v;scanf("%d %d", &u, &v);link(u, v);}for(int i = 0;i < p;i ++){int u, v;scanf("%d %d", &u, &v);if(link(u, v)){printf("%d\n", cnt[fd(u)]);}else{printf("No\n");}}return 0;
}
http://www.jsqmd.com/news/396705/

相关文章:

  • 如何选择可靠手表维修点?2026年北京海鸥手表维修评测与推荐,直击非官方与乱报价痛点 - 十大品牌推荐
  • 如何选择维修点?2026年北京法穆兰手表维修推荐与排名,直击技术隐忧 - 十大品牌推荐
  • 2026年北京梵克雅宝手表维修推荐:高端腕表保养深度评价,涵盖复杂机芯与日常维护场景 - 十大品牌推荐
  • 2026年北京冠蓝狮手表维修推荐:多场景服务评价与排名,直击非官方维修站信任痛点 - 十大品牌推荐
  • 如何选择可靠维修点?2026年北京冠蓝狮手表维修推荐与评测,直击服务与网点痛点 - 十大品牌推荐
  • 2026年北京蒂芙尼手表维修推荐:官方售后与授权网点评测,解决维修无门与高价痛点 - 十大品牌推荐
  • 如何选择可靠维修点?2026年北京格拉苏蒂原创手表维修推荐与评价,解决非官方维修痛点 - 十大品牌推荐
  • 维修网点哪家强?2026年北京东方双狮手表维修推荐与评价,应对时效与沟通痛点 - 十大品牌推荐
  • Springboot3+vue3实现登录注册功能
  • 如何选择可靠维修点?2026年北京蒂芙尼手表维修排名与推荐,直击非官方服务痛点 - 十大品牌推荐
  • 如何选择可靠维修点?2026年北京蒂芙尼手表维修推荐与评价,直击售后与网点覆盖痛点 - 十大品牌推荐
  • 如何选择手表维修点?2026年北京东方双狮维修推荐与评价,直击配件与工艺痛点 - 十大品牌推荐
  • 帝舵手表维修哪家靠谱?2026年北京维修站推荐与评价,解决配件真伪核心痛点 - 十大品牌推荐
  • 2026年北京帝舵手表维修推荐:专业维修站排名,涵盖日常保养与复杂故障场景 - 十大品牌推荐
  • Python基于flask框架教师科研项目管理系统可视化-Pycharm django
  • Simulink永磁同步电机(PMSM)基于滑模观测器的无位置传感器控制仿真模型 附资料
  • 如何选择可靠维修点?2026年北京迪奥手表维修推荐与排名,直击服务标准不一痛点 - 十大品牌推荐
  • Python基于flask框架社区物业车位缴费房屋充电桩管理系统 论文-Pycharm django
  • [Kaleidoscope of Physics] 广义坐标
  • 2026年北京迪奥手表维修推荐:基于多场景服务评价,针对维修质量与中心透明度痛点 - 十大品牌推荐
  • Python基于flask框架健康饮食营养管理信息系统-Pycharm django
  • P10658 BZOJ2959 长跑
  • Python基于flask框架基于高性能计算中心课题任务提交平台的高性能集群共享平台-Pycharm django
  • 武商一卡通回收注意事项:如何安全高效地处理闲置卡片? - 团团收购物卡回收
  • Python基于flask框架教务选课成绩管理系统设计与实现eq8s1x2l-Pycharm django
  • Python基于flask框架-美妆化妆品商城进货系统-Pycharm django
  • 毕业论文神器 9个降AI率平台深度测评与推荐
  • 这份榜单够用!10个AI论文工具测评:本科生毕业论文+科研写作必备神器
  • 【MyBatis Exception】@Param注解List参数。Parameter ‘tigerList‘ not found Available parameters
  • 美妆购物网站信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】