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 双连通分量 并查集]相关推荐

  1. BZOJ 2959 长跑 (LCT、并查集)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2959 题解 真是被这题搞得心态大崩--调了7个小时--然而并查集都能写成\(O(n^2) ...

  2. BZOJ 2959 长跑 LCT+动态边双

    题意: 支持加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树. 分析: 这个题我们需要知道,假如两点间有环,那么无论如何,这个环上所有的价值都可以被我们获得. 有环,还有这个性质,我们可 ...

  3. POJ 3694 Network ★(边双连通分量+并查集缩点+LCA)

    [题意]一个无向图可以有重边,下面q个操作,每次在两个点间连接一条有向边,每次连接后整个无向图还剩下多少桥(每次回答是在上一次连边的基础之上) [分析]好题,做完后涨了很多姿势~ 普通做法当然就是每加 ...

  4. bzoj 2959: 长跑(LCT+并查集)

    2959: 长跑 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 315  Solved: 178 [Submit][Status][Discuss] ...

  5. BZOJ 2959: 长跑 解题报告

    2959: 长跑 Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑 ...

  6. [BZOJ]2959: 长跑

    题解:   我们考虑一条链时 答案为链上和  路径上有环时  这个环上的点都会产生贡献  然后我们可以 用并查集来维护LCT  有环时直接缩成一个点即可 #include <algorithm& ...

  7. BZOJ 2959 - 长跑

    题意 每个点有各自的权值,要求维护操作:动态加边.动态修改权值.询问在每个点只能经过一次的情况下两点间路程中的最大权值和 题解 首先对于一个静态的图,将其缩点,可以得到一棵树,那么两点间询问的答案即为 ...

  8. 【POJ - 3694】Network(对dfn求lca 或 缩点+lca 或 边双连通+并查集)

    题干: 网络管理员管理大型网络.该网络由N台计算机和成对计算机之间的M链路组成.任何一对计算机都通过连续的链接直接或间接连接,因此可以在任何两台计算机之间转换数据.管理员发现某些链接对网络至关重要,因 ...

  9. [BZOJ 3211]花神游历各国(并查集+树状数组)

    Description Solution 树状数组单点修改区间查询 我们知道一个数n最多修改loglogn次就会变为1 并查集维护每个数右边第一个不为1的位置 #include<cstdio&g ...

最新文章

  1. “智享未来 知行合一”,开为科技AI产品发布会于2月6日召开
  2. python 管道游戏_Python实现超级玛丽游戏系列教程05添加地面,管道和阶梯冲突检测...
  3. ASP.net中页面事件的先后顺序
  4. 图形验证码最佳攻略2
  5. windows环境下安装python的mysqldb模块
  6. python3.7安装包百度云_Python-3.7.0软件安装包以及安装教程
  7. 【数据库原理及应用】经典题库附答案(14章全)——第六章:关系数据库设计过程
  8. android 素材标签,Android Studio矢量素材资源导入错误 – 不支持标签
  9. 管理感悟:怎样讲清楚自己的想法
  10. 家谱族谱软件用云码宗谱
  11. python采集修改原创_火车头采集标题如何伪原创(附教程)
  12. 利用python脚本将微信聊天信息提取到txt文件
  13. 考研数据结构之栈(2.5)——练习题之求解二次方根A的迭代函数,写出相应的递归算法和非递归算法(C表示)
  14. 安卓webview的一些坑
  15. 民营企业的十三种死法
  16. 论文免费检测网站分享
  17. SD卡格式化和删除分区
  18. OpenCV 图片合成视频
  19. CocosCreator之节点如何做圆周运动
  20. 最新WIN10系统封装教程2019系列(八)——测试效果

热门文章

  1. sql截去最后一位_sql 取最后一条记录
  2. jpa hibernate mysql_008Spring JPA Hibernate MySQL
  3. 论文笔记之:Let there be Color!: Joint End-to-end Learning of Global and Local Image Priors for Automatic
  4. Haar-like特征
  5. 【AutoML】当前有哪些可用的AutoML平台?
  6. 【知识星球】每日干货看图猜技术,你都会吗?
  7. 【AI白身境】学AI必备的python基础
  8. 中国香皂行业产量份额预测与消费需求商机研究报告2022年
  9. 2022年全球及中国固态电解质(SSE)行业应用现状与十四五投资潜力分析报告
  10. 中国城市商业银行产业模式展望及布局规模前景分析报告2021-2027年