【BZOJ2959】长跑 (LCT+并查集)
Time Limit: 1000 ms Memory Limit: 256 MB
Description
某校开展了同学们喜闻乐见的阳光长跑活动。为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动。一时间 操场上熙熙攘攘,摩肩接踵,盛况空前。
为了让同学们更好地监督自己,学校推行了刷卡机制。
学校中有n个地点,用1到n的整数表示,每个地点设有若干个刷卡机。
有以下三类事件:
1、修建了一条连接A地点和B地点的跑道。
2、A点的刷卡机台数变为了B。
3、进行了一次长跑。问一个同学从A出发,最后到达B最多可以刷卡多少次。具体的要求如下:
当同学到达一个地点时,他可以在这里的每一台刷卡机上都刷卡。但每台刷卡机只能刷卡一次,即使多次到达同一地点也不能多次刷卡。
为了安全起见,每条跑道都需要设定一个方向,这条跑道只能按照这个方向单向通行。最多的刷卡次数即为在任意设定跑道方向,按照任意路径从A地点到B地点能刷卡的最多次数。
Input
输入的第一行包含两个正整数n,m,表示地点的个数和操作的个数。
第二行包含n个非负整数,其中第i个数为第个地点最开始刷卡机的台数。
接下来有m行,每行包含三个非负整数P,A,B,P为事件类型,A,B为事件的两个参数。
最初所有地点之间都没有跑道。
每行相邻的两个数之间均用一个空格隔开。表示地点编号的数均在1到n之间,每个地点的刷卡机台数始终不超过10000,P=1,2,3。
Output
输出的行数等于第3类事件的个数,每行表示一个第3类事件。如果该情况下存在一种设定跑道方向的方案和路径的方案,可以到达,则输出最多可以刷卡的次数。如果A不能到达B,则输出-1。
Sample Input And Output Are Too Long>_<
Hint
对于100%的数据,m<=5n,任意时刻,每个地点的刷卡机台数不超过10000。
具体每组数据的规模如下
$30\%: n \leq 5000 $
$100\%: 1 \leq n \leq 150000, 1 \leq m \leq 5n, 0 \leq v_i \leq 10000$
题解
PS:我原来以为是有向图结果不会做,后来发现我被题面坑了......
题意是动态维护加入无向边,修改点权的操作;询问对每条边设置方向之后,A到B的点权之和最大值。
如果某一些点构成了双联通分量,那么可以考虑将这些点缩成一个点,其点权为所有点之和,原本连向这些点的边都连向代表点。
那么如果支持动态缩点,那么整个图保持为一棵树,询问A到B即询问树上A所属代表元到B所属代表元的点权和,这可以用LCT维护。
那么看看怎么缩点:
用一个并查集维护每一个点的代表元,怎么维护?
考虑每一次连边$(u,v)$:
首先我们把$u$赋值为$u$的代表元,$v$赋值为$v$的代表元。
1. 如果$u$和$v$原本不连通,那么直接连上。
2.如果$u$和$v$原本已经连通,需要将$u$到$v$的路径缩成一个点,那么就在LCT上提取出$u$到$v$的路径,makeroot(u);access(v);splay(v);放到一棵Splay里就好。干脆就把v当做代表元好了,那么v自带的信息已经是所有点的权值之和,接下来遍历一遍这一棵Splay,将所有点的并查集父亲设置为$v$,就完成了缩点。
那么对于LCT,缩点是怎么体现的呢?
在并查集已经维护好的情况下,我们每次$access(u)$时,原本是迭代为父亲,现在直接迭代为父亲的代表元。为什么这样是对的?对于一棵已经缩点的Splay,从下面的别的Splay$access$上来的时候,不可以再对这些已经缩了的点进行操作了,直接找到代表元来操作。由此,$access$的迭代不再是连续的了;若当前点为$u$,上一个点为$v$,那么要额外修正$v$的父亲为$u$。
这样维护,对于LCT自身的维护是没有影响的,所以不用操心啦。
#include <cstdio>
using namespace std;
typedef long long ll;
const int N=;
int n,m,bl[N];
int ch[N][],fa[N],rev[N];
ll w[N],val[N],sum[N];
inline ll rd(){
ll x=;
char c;
while((c=getchar())<''||c>'');
x=c-'';
while(''<=(c=getchar())&&c<='') x=x*+c-'';
return x;
}
inline int find(int x){return bl[x]==x?x:bl[x]=find(bl[x]);};
inline void swap(int &x,int &y){int t=x;x=y;y=t;}
inline bool isRoot(int u){return ch[fa[u]][]!=u&&ch[fa[u]][]!=u;}
inline bool who(int u){return ch[fa[u]][]==u;}
inline void reverse(int u){
rev[u]^=;
swap(ch[u][],ch[u][]);
}
inline void pushup(int u){
sum[u]=sum[ch[u][]]+sum[ch[u][]]+val[u];
}
inline void rotate(int u){
int f=fa[u],g=fa[f],c=who(u);
if(!isRoot(f)) ch[g][who(f)]=u;
fa[u]=g;
ch[f][c]=ch[u][c^];
if(ch[f][c]) fa[ch[f][c]]=f;
ch[u][c^]=f;
fa[f]=u;
pushup(f);
pushup(u);
}
inline void pd(int u){
if(rev[u]){
if(ch[u][]) reverse(ch[u][]);
if(ch[u][]) reverse(ch[u][]);
rev[u]=;
}
}
inline void pushdown(int u){
if(!isRoot(u)) pushdown(fa[u]);
pd(u);
}
inline void splay(int u){
pushdown(u);
while(!isRoot(u)){
if(!isRoot(fa[u]))
rotate(who(fa[u])==who(u)?fa[u]:u);
rotate(u);
}
}
inline void access(int u){
for(int v=;u;v=u,u=find(fa[u])){
splay(u);
ch[u][]=v;
fa[v]=u;
pushup(u);
}
}
inline void makeRoot(int u){
access(u);
splay(u);
reverse(u);
}
inline bool isConnect(int a,int b){
if(a==b) return true;
makeRoot(a);
access(b);
splay(b);
return fa[a];
}
void shrink(int u,int target){
if(!u) return;
bl[u]=target;
shrink(ch[u][],target);
shrink(ch[u][],target);
}
inline void link(int a,int b){
a=find(a); b=find(b);
if(a==b) return;
if(isConnect(a,b)){
makeRoot(a);
access(b);
splay(b);
shrink(b,b);
val[b]=sum[b];
}
else{
makeRoot(a);
fa[a]=b;
}
}
inline void change(int a,int b){
ll delta=b-w[a];
w[a]=b;
a=find(a);
val[a]+=delta;
sum[a]+=delta;
splay(a);
}
inline ll query(int a,int b){
a=find(a); b=find(b);
if(!isConnect(a,b)) return -;
if(a==b) return val[a];
makeRoot(a);
access(b);
splay(b);
return sum[b];
}
int main(){
n=rd(); m=rd();
for(int i=;i<=n;i++) w[i]=val[i]=rd();
for(int i=;i<=n;i++) bl[i]=i;
int opt,a,b;
while(m--){
opt=rd(); a=rd(); b=rd();
switch(opt){
case : link(a,b); break;
case : change(a,b); break;
case : printf("%lld\n",query(a,b)); break;
}
}
return ;
}
奇妙代码
【BZOJ2959】长跑 (LCT+并查集)的更多相关文章
- BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...
- bzoj2959: 长跑(LCT+并查集)
题解 动态树Link-cut tree(LCT)总结 LCT常数大得真实 没有环,就是\(lct\)裸题吧 有环,我们就可以绕环转一圈,缩点 怎么搞? 当形成环时,把所有点的值全部加到一个点上,用并查 ...
- bzoj2959: 长跑 LCT+并查集+边双联通
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2959 题解 调了半天,终于调完了. 显然题目要求是求出目前从 \(A\) 到 \(B\) 的可 ...
- 【bzoj2959】长跑 LCT+并查集
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前.为了 ...
- BZOJ 2959 长跑 (LCT+并查集)
题面:BZOJ传送门 当成有向边做的发现过不去样例,改成无向边就忘了原来的思路.. 因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和 这样保证了图是一颗森林 每次询问转化为, ...
- 【bzoj4998】星球联盟 LCT+并查集
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...
- bzoj 2959: 长跑【LCT+并查集】
如果没有环的话直接LCT 考虑有环怎么办,如果是静态的话就tarjan了,但是这里要动态的缩环 具体是link操作的时候看一下是否成环(两点已联通),成环的话就用并查集把这条链缩到一个点,把权值加给祖 ...
- bzoj4998 星球联盟 LCT + 并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4998 题解 根据题意,就是要动态维护点双,求出一个点双的权值和. 所以这道题就是和 bzoj2 ...
- BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两 ...
随机推荐
- 输入和输出--java序列化机制
对象的序列化 什么是Java对象的序列化? 对象序列化的目标是将对象保存到磁盘上,或允许在网络中直接传输对象.对象序列化机制允许把内存中的Java对象转换成与平台无关的二进制流,从而保存或者传输.其他 ...
- shell第四篇(下)
摘自王垠的:Unix的缺陷 我想通过这篇文章解释一下我对 Unix 哲学本质的理解.我虽然指出 Unix 的一个设计问题,但目的并不是打击人们对 Unix 的兴趣.虽然 Unix 在基础概念上有一个挺 ...
- VMware10不能安装64位(linux)系统,提示此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态
今天下载VM10准备安装Ubuntu14.04,一如既往的进行安装,突然发现出现了问题:此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态,具体如图: 如图中提示可重启电脑进入B ...
- H5 Canvas图像模糊解决办法
1.最近在用h5的canvas画动画,发现图像特别模糊.后来终于找到罪魁祸首是<meta name="viewport" content="width=device ...
- excel中的数据导出为properties和map的方法
在做项目的过程中,经常需要处理excel数据,特别是和业务人员配合时,业务人员喜欢使用excel处理一些数据,然后交给我们技术人员进行程序处理.利用POI读取写入excel数据,是经常使用的一个情景. ...
- Django的ORM实现数据库事务操作
在Django中实现数据库的事务操作 在学习MySQL数据库时,MySQL数据库是支持原子操作的. 什么是数据库的原子操作呢??打个比方,一个消费者在一个商户里刷信用卡消费. 交易正常时,银行在消费者 ...
- 单元测试系列:Mock工具之Mockito实战
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6780719.html 在实际项目中写单 ...
- iOS设备唯一标识的前世今生
设备唯一标识 估计很多开发都有被要求过获取一下设备的唯一标识,获取设备的唯一标识经常使用在我们做统计或者是在保证一台设备登录亦或者是做IM的时候可能会考虑去使用它,这一次在自己的需求当中就有一个&qu ...
- bzoj 1930: [Shoi2003]pacman 吃豆豆 [费用流]
1930: [Shoi2003]pacman 吃豆豆 题意:两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的 ...
- bzoj 2655: calc [容斥原理 伯努利数]
2655: calc 题意:长n的序列,每个数\(a_i \in [1,A]\),求所有满足\(a_i\)互不相同的序列的\(\prod_i a_i\)的和 clj的题 一下子想到容斥,一开始从普通容 ...