BZOJ 2959 长跑 LCT+动态边双
题意:
支持加入边,修改点权,询问两点间走一条路径的最大点权和。不一定是树。
分析:
这个题我们需要知道,假如两点间有环,那么无论如何,这个环上所有的价值都可以被我们获得。
有环,还有这个性质,我们可以自然而然的想到边双联通分量缩点,但是我们不能对于每次加边就重构一下图,更不能每次询问都求一遍最大路,所以我们就需要一个灵活的LCT来维护我们的操作。
我们用并查集辅助,用一个并查集维护连通性,再用一个并查集维护每个原始点属于哪个新的边双联通分量。
当我们连接一条边时,如果两个点不连通,那么我们直接将其连通。
如果本身已经连通,那么我们就在LCT上把这两个点之间的链搞到一个splay上,然后dfs一遍,把链上所有的点都弄进一个双连通分量里(就是用并查集并起来),继而把这些点从splay上删掉,只留一个根节点,将整个环的价值赋给它。
修改点权的时候,我们直接把原始点的权值修改,然后算出所在连通分量的总权值应该怎样变化即可。
至此,回答询问也就是自然而然的事情了。
代码:
1 #include<bits/stdc++.h> 2 #define max(a,b,c) max(max(a,b),c) 3 #define lc(x) t[x][0] 4 #define rc(x) t[x][1] 5 using namespace std; 6 const int N=150005; 7 int t[N][2],rev[N],val[N],sm[N],fu[N]; 8 int s[N],tp,n,m,k,fa[N],Fa[N],q,v[N]; 9 //并查集----------------------------------------↓ 10 int get(int x){ 11 return x==fa[x]?x:fa[x]=get(fa[x]); 12 } int Get(int x){ 13 return x==Fa[x]?x:Fa[x]=Get(Fa[x]); 14 } 15 //并查集----------------------------------------↑ 16 //LCT-------------------------------------------↓ 17 void pushup(int x){ 18 sm[x]=sm[lc(x)]+sm[rc(x)]+val[x]; 19 } void revers(int x){ 20 rev[x]^=1;swap(lc(x),rc(x)); 21 } void pushdown(int x){ 22 if(rev[x]){ 23 if(lc(x)) revers(lc(x)); 24 if(rc(x)) revers(rc(x)); 25 } rev[x]=0;return ; 26 } bool pdrt(int x){ 27 return lc(get(fu[x]))!=x&&rc(get(fu[x]))!=x; 28 } void rotate(int x){ 29 int y=get(fu[x]);int z=get(fu[y]); 30 int dy=(rc(y)==x),dz=(rc(z)==y); 31 if(!pdrt(y)) t[z][dz]=x; 32 t[y][dy]=t[x][dy^1];fu[t[y][dy]]=y; 33 t[x][dy^1]=y;fu[y]=x;fu[x]=z;pushup(y); 34 } void splay(int x){ 35 s[++tp]=x; 36 for(int i=x;!pdrt(i);i=fu[i]) 37 s[++tp]=get(fu[i]); 38 while(tp) pushdown(s[tp--]); 39 while(!pdrt(x)){ 40 int y=get(fu[x]);int z=get(fu[y]); 41 if(!pdrt(y)) 42 if(rc(y)==x^rc(z)==y) rotate(x); 43 else rotate(y);rotate(x); 44 } pushup(x); 45 } void access(int x){ 46 for(int i=0;x;x=get(fu[x])) 47 splay(x),rc(x)=i,i=x; 48 } void mkrt(int x){ 49 access(x);splay(x);revers(x); 50 } int fdrt(int x){ 51 access(x),splay(x); 52 while(lc(x)) pushdown(x),x=lc(x); 53 return x; 54 } void split(int x,int y){ 55 mkrt(x);access(y);splay(y); 56 } void link(int x,int y){ 57 mkrt(x);if(fdrt(y)!=x) fu[x]=y; 58 } void cut(int x,int y){ 59 mkrt(x); 60 if(fdrt(y)==x&&fu[y]==x&&!rc(x)) 61 fu[x]=t[y][0]=0;pushup(y); 62 } 63 //LCT-------------------------------------------↑ 64 //DFS-------------------------------------------↓ 65 void dfs(int x,int y){ 66 fa[x]=y;pushdown(x); 67 if(lc(x)) dfs(lc(x),y); 68 if(rc(x)) dfs(rc(x),y); 69 } 70 //DFS-------------------------------------------↑ 71 int main(){ 72 scanf("%d%d",&n,&m); 73 for(int i=1;i<=n;i++) 74 scanf("%d",&v[i]),Fa[i]=i, 75 val[i]=s[i]=v[i],fa[i]=i; 76 for(int i=1,op,a,b;i<=m;i++){ 77 scanf("%d%d%d",&op,&a,&b); 78 if(op==1){ 79 a=get(a),b=get(b); 80 if(a==b) continue; 81 split(a,b); 82 if(Get(a)!=Get(b)) 83 fu[a]=b,Fa[Fa[a]]=Fa[b]; 84 else val[b]=sm[b],dfs(b,b), 85 t[b][0]=t[b][1]=0; 86 } int d;if(op==2) 87 d=a,a=get(a),splay(a), 88 val[a]+=b-v[d],v[d]=b,pushup(a); 89 if(op==3){ 90 a=get(a),b=get(b); 91 if(Get(a)!=Get(b)) puts("-1"); 92 else split(a,b),printf("%d\n",sm[b]); 93 } 94 } return 0; 95 }
LCT
转载于:https://www.cnblogs.com/Alan-Luo/articles/10157263.html
BZOJ 2959 长跑 LCT+动态边双相关推荐
- BZOJ 2959: 长跑 [lct 双连通分量 并查集]
2959: 长跑 题意:字词加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树 不是树? 把边双连通分量缩为一点! 怎么缩? 用一个并查集维护连通性,另一个并查集维护每个点所在边双的编号, ...
- BZOJ 2959 长跑 (LCT、并查集)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2959 题解 真是被这题搞得心态大崩--调了7个小时--然而并查集都能写成\(O(n^2) ...
- 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 长跑
Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上 ...
- BZOJ 2959 - 长跑
题意 每个点有各自的权值,要求维护操作:动态加边.动态修改权值.询问在每个点只能经过一次的情况下两点间路程中的最大权值和 题解 首先对于一个静态的图,将其缩点,可以得到一棵树,那么两点间询问的答案即为 ...
- 如何为***选择合适的动态密码双因素认证方案
CKEY动态密码认证是双因子认证的一种方式,×××用户增加动态密码认证,借助此方案可以提升×××远程拨入安全,加强登陆用户审计. CKEY为×××提供短信密码.硬件令牌.软件令牌.短信密码+硬件令牌混 ...
- HYSBZ - 2959 长跑(动态树+并查集)
某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况 ...
最新文章
- datagrid DataFormatString
- 人天生就会除法,宾大最新研究:儿童啥都不学也能算出来
- matlab极大值点个数,求一组数的极大值个数
- 卓越软件工程--《微软360度》读后感
- [转]马云在《赢在中国》对创业者的经典点评
- 教学目标四个维度_挖掘教材 预设目标 思本归真—— 记临安区初二英语教学研讨会...
- 双代号网络图基础算法_最新(免锁版)网络图横道图绘制软件,内附安装教程,制图做更快...
- (转)Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
- 新年发财专属红包封面,高端大气上档次!
- 手把手教你制作easyUI+bootstrap工作站,主要学习tabs方法
- c语言,求素数个数,关于求素数个数的话题
- typescript面试题_vue 248+个知识点(面试题)为你保驾护航
- 2022年上半年系统分析师上午真题及答案解析
- Django之jsonp跨域请求原理
- 课堂派题库格式转换程序
- Github项目精选:2021年6月优秀项目推荐
- Java返回Json文件
- 国产之路:复旦微调试笔记3:环境配置
- SiteMap(站点地图)
- 计算机科学与技术专业学长,2017级计算机科学与技术专业成功举办优秀就业学长经验交流会...
热门文章
- 忽略非数据库字段的注解
- 【性能】【内存】zram解读
- java逻辑运算符之异或
- ASO优化之关于应用宝的关键词排名
- 洛谷 P2756 飞行员配对方案问题 二分图 匈牙利算法 链式前向星 汉子找妹子模型 最大流模板 FF算法
- 闲鱼java系统_java爬取闲鱼商品信息(一)
- 修改WIN10D盘默认盘符
- 1:9 error Component name ““ should always be multi-word
- 云时代架构之点融支付系统架构的演进
- 不同表格查找重复数据VBA