BZOJ 2959: 长跑 [lct 双连通分量 并查集]
2959: 长跑
题意:字词加入边,修改点权,询问两点间走一条路径的最大点权和。不一定是树
不是树?
把边双连通分量缩为一点!
怎么缩?
用一个并查集维护连通性,另一个并查集维护每个点所在边双的编号,初始化就是自己。
加边(x,y)的时候,如果形成环,那么把x到y的路径提取出来,把这个splay变成一个点就行了
注意:其他的点会有父亲连向缩点的bcc中的其他点,access的时候会用到轻边连向的父亲,需要使用并查集来找fa,并且要重设父亲,一开始没处理这里
清橙上T了4个点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lc t[x].ch[0]
#define rc t[x].ch[1]
#define pa t[x].fa
typedef long long ll;
const int N=3e5+5;
inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}int n, Q, op, x, y, val[N];
struct ufs {int fa[N];int find(int x) {return x==fa[x] ? x : fa[x]=find(fa[x]);}inline void unn(int x, int y) {fa[find(x)]=find(y);}inline void ini(int n) {for(int i=1; i<=n; i++) fa[i]=i;}
}a, b;namespace lct {struct meow {int ch[2], fa, rev, sum, w;} t[N];inline int wh(int x) {return t[pa].ch[1] == x;}inline int isr(int x) {return t[pa].ch[0] != x && t[pa].ch[1] != x;}inline void update(int x) {t[x].sum = t[lc].sum + t[rc].sum + t[x].w;}inline void rever(int x) {t[x].rev ^= 1; swap(lc, rc);}inline void pushdn(int x) {if(t[x].rev) {if(lc) rever(lc);if(rc) rever(rc);t[x].rev = 0;}}void pd(int x) {if(!isr(x)) pd(pa); pushdn(x);}inline void rotate(int x) {int f=t[x].fa, g=t[f].fa, c=wh(x);if(!isr(f)) t[g].ch[wh(f)]=x; t[x].fa=g;t[f].ch[c] = t[x].ch[c^1]; t[t[f].ch[c]].fa=f;t[x].ch[c^1]=f; t[f].fa=x;update(f); update(x);}inline void splay(int x) {pd(x);for(; !isr(x); rotate(x))if(!isr(pa)) rotate(wh(x)==wh(pa) ? pa : x);}void see(int x) {if(lc) see(lc); printf("%d ",x); if(rc) see(rc);}inline void access(int x) {for(int y=0; x; y=x, x = b.find(pa)) // light_fasplay(x), rc=y, t[y].fa=x, update(x);}inline void maker(int x) {access(x); splay(x); rever(x);}inline void link(int x, int y) { //printf("lct::link %d %d\n",x,y);maker(x); t[x].fa=y;}inline void split(int x, int y) { //printf("split %d %d\n",x,y);maker(x); access(y); splay(y); //printf("yyy %d %d %d\n",y,t[y].ch[0],t[y].sum);}int q[N], head, tail;inline void rebuild(int x, int y) { //all(x, y) --> ysplit(x, y);//see(y); puts(" see");head=tail=1; q[tail++]=y;while(head != tail) {int x = q[head++]; b.fa[x] = y; //printf("x %d\n",x);if(lc) q[tail++]=lc;if(rc) q[tail++]=rc;lc = rc = 0;}t[y].w = t[y].sum;}}void Link(int x, int y) {x = b.find(x); y = b.find(y);if(x == y) return;int f1=a.find(x), f2=a.find(y); //printf("\nLink %d %d %d %d\n",x,y,f1,f2);if(f1 != f2) lct::link(x, y), a.unn(x, y);else lct::rebuild(x, y);
}
void Add(int x, int y) {x = b.find(x);lct::t[x].w += y; lct::splay(x);
}
int Que(int x, int y) { //printf("\nQue %d %d\n",x,y);if(a.find(x) != a.find(y)) return -1;x = b.find(x); y = b.find(y); //printf("x y %d %d\n",x,y);if(x == y) return lct::t[x].w;lct::split(x, y);return lct::t[y].sum;
}int main() {freopen("in","r",stdin);n=read(); Q=read();a.ini(n); b.ini(n);for(int i=1; i<=n; i++) val[i] = lct::t[i].w = read();for(int i=1; i<=Q; i++) { //puts("");op=read(); x=read(); y=read();if(op==1) Link(x, y);if(op==2) Add(x, y-val[x]), val[x]=y;if(op==3) printf("%d\n", Que(x, y));}
}
BZOJ 2959: 长跑 [lct 双连通分量 并查集]相关推荐
- BZOJ 2959 长跑 (LCT、并查集)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2959 题解 真是被这题搞得心态大崩--调了7个小时--然而并查集都能写成\(O(n^2) ...
- BZOJ 2959 长跑 LCT+动态边双
题意: 支持加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树. 分析: 这个题我们需要知道,假如两点间有环,那么无论如何,这个环上所有的价值都可以被我们获得. 有环,还有这个性质,我们可 ...
- POJ 3694 Network ★(边双连通分量+并查集缩点+LCA)
[题意]一个无向图可以有重边,下面q个操作,每次在两个点间连接一条有向边,每次连接后整个无向图还剩下多少桥(每次回答是在上一次连边的基础之上) [分析]好题,做完后涨了很多姿势~ 普通做法当然就是每加 ...
- bzoj 2959: 长跑(LCT+并查集)
2959: 长跑 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 315 Solved: 178 [Submit][Status][Discuss] ...
- BZOJ 2959: 长跑 解题报告
2959: 长跑 Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑 ...
- [BZOJ]2959: 长跑
题解: 我们考虑一条链时 答案为链上和 路径上有环时 这个环上的点都会产生贡献 然后我们可以 用并查集来维护LCT 有环时直接缩成一个点即可 #include <algorithm& ...
- BZOJ 2959 - 长跑
题意 每个点有各自的权值,要求维护操作:动态加边.动态修改权值.询问在每个点只能经过一次的情况下两点间路程中的最大权值和 题解 首先对于一个静态的图,将其缩点,可以得到一棵树,那么两点间询问的答案即为 ...
- 【POJ - 3694】Network(对dfn求lca 或 缩点+lca 或 边双连通+并查集)
题干: 网络管理员管理大型网络.该网络由N台计算机和成对计算机之间的M链路组成.任何一对计算机都通过连续的链接直接或间接连接,因此可以在任何两台计算机之间转换数据.管理员发现某些链接对网络至关重要,因 ...
- [BZOJ 3211]花神游历各国(并查集+树状数组)
Description Solution 树状数组单点修改区间查询 我们知道一个数n最多修改loglogn次就会变为1 并查集维护每个数右边第一个不为1的位置 #include<cstdio&g ...
最新文章
- “智享未来 知行合一”,开为科技AI产品发布会于2月6日召开
- python 管道游戏_Python实现超级玛丽游戏系列教程05添加地面,管道和阶梯冲突检测...
- ASP.net中页面事件的先后顺序
- 图形验证码最佳攻略2
- windows环境下安装python的mysqldb模块
- python3.7安装包百度云_Python-3.7.0软件安装包以及安装教程
- 【数据库原理及应用】经典题库附答案(14章全)——第六章:关系数据库设计过程
- android 素材标签,Android Studio矢量素材资源导入错误 – 不支持标签
- 管理感悟:怎样讲清楚自己的想法
- 家谱族谱软件用云码宗谱
- python采集修改原创_火车头采集标题如何伪原创(附教程)
- 利用python脚本将微信聊天信息提取到txt文件
- 考研数据结构之栈(2.5)——练习题之求解二次方根A的迭代函数,写出相应的递归算法和非递归算法(C表示)
- 安卓webview的一些坑
- 民营企业的十三种死法
- 论文免费检测网站分享
- SD卡格式化和删除分区
- OpenCV 图片合成视频
- CocosCreator之节点如何做圆周运动
- 最新WIN10系统封装教程2019系列(八)——测试效果
热门文章
- sql截去最后一位_sql 取最后一条记录
- jpa hibernate mysql_008Spring JPA Hibernate MySQL
- 论文笔记之:Let there be Color!: Joint End-to-end Learning of Global and Local Image Priors for Automatic
- Haar-like特征
- 【AutoML】当前有哪些可用的AutoML平台?
- 【知识星球】每日干货看图猜技术,你都会吗?
- 【AI白身境】学AI必备的python基础
- 中国香皂行业产量份额预测与消费需求商机研究报告2022年
- 2022年全球及中国固态电解质(SSE)行业应用现状与十四五投资潜力分析报告
- 中国城市商业银行产业模式展望及布局规模前景分析报告2021-2027年