BZOJ 2959: 长跑 lct 双联通分量 并查集 splay
http://www.lydsy.com/JudgeOnline/problem.php?id=2959
用两个并查集维护双联通分量的编号和合并。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=;
int n,m;
int fa[maxn]={},ch[maxn][]={},siz[maxn]={},val[maxn]={},rev[maxn];
int shu[maxn]={};
int sta[maxn]={},tail=;
int p[maxn]={},b[maxn]={};
inline int read(){
int x=;int f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;
ch=getchar();
}
while(''<=ch&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int findfa(int x){
if(p[x]==x)return x;
return p[x]=findfa(p[x]);
}
int bel(int x){
if(b[x]==x)return x;
return b[x]=bel(b[x]);
}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void updata(int x){ siz[x]=siz[ch[x][]]+siz[ch[x][]]+val[x];}
inline void rotate(int x){
int y=fa[x];int fy=fa[y];
int l=ch[y][]==x?:;int r=l^;
if(!isroot(y)){
if(ch[fy][]==y)ch[fy][]=x;
else ch[fy][]=x;
}
fa[ch[x][r]]=y;fa[y]=x;fa[x]=fy;
ch[y][l]=ch[x][r]; ch[x][r]=y;
updata(y);
}
inline void pushdown(int x){
if(rev[x]){
swap(ch[x][],ch[x][]);
if(ch[x][])rev[ch[x][]]^=;
if(ch[x][])rev[ch[x][]]^=;
rev[x]=;
}
}
inline void splay(int x){
x=bel(x);fa[x]=bel(fa[x]);
int y,fy,w=x;
sta[++tail]=w;
while(!isroot(w)){
fa[w]=bel(fa[w]);sta[++tail]=fa[w];
fa[fa[w]]=bel(fa[fa[w]]);
w=fa[w];
}
while(tail)pushdown(sta[tail--]); while(!isroot(x)){
y=fa[x];fy=fa[y];
if(!isroot(y)){
if((ch[y][]==x)^(ch[fy][]==y))rotate(x);
else rotate(y);
}rotate(x);
}updata(x);
}
inline void Access(int x){
int y=;
while(x){
x=bel(x);
splay(x);ch[x][]=y;
updata(x);
y=x;x=fa[x];
}
}
inline void Reverse(int x){
Access(x);splay(x);
rev[x]^=;
}
inline void Link(int x,int y){
Reverse(x);fa[x]=y;
}
queue< int >q;
inline void Merge(int x,int y){
Reverse(y);Access(x);splay(x);
int cnt=siz[x];
q.push(x);
while(!q.empty()){
x=q.front();q.pop();
if(ch[x][])q.push(ch[x][]);
if(ch[x][])q.push(ch[x][]);
b[bel(x)]=b[bel(y)];
val[x]=siz[x]=fa[x]=ch[x][]=ch[x][]=;
}
val[y]=siz[y]=cnt;fa[y]=;
}
int main(){
//freopen("now.in","r",stdin);
n=read();m=read();;
for(int i=;i<=n;i++){val[i]=read();shu[i]=val[i];siz[i]=val[i];}
for(int i=;i<=n;i++)p[i]=i,b[i]=i;
int op,x,y,xx,yy;
for(int i=;i<=m;i++){
op=read();x=read();y=read();
if(op==){
x=bel(x);y=bel(y);
if(x!=y){
xx=findfa(x);yy=findfa(y);
if(xx==yy) Merge(x,y);
else {Link(x,y);p[xx]=yy;}
}
}
else if(op==){
xx=bel(x);
if(shu[x]!=y){
Access(xx);splay(xx);
siz[xx]+=y-shu[x];
val[xx]+=y-shu[x];
shu[x]=y;
}
}
else{
x=bel(x);y=bel(y);
if(findfa(x)!=findfa(y)){
printf("-1\n");
}
else{
Reverse(x);Access(y);splay(y);
printf("%d\n",siz[y]);
}
}
}
return ;
}
注意一下双联通分量编号的维护
BZOJ 2959: 长跑 lct 双联通分量 并查集 splay的更多相关文章
- BZOJ 2959: 长跑 [lct 双连通分量 并查集]
2959: 长跑 题意:字词加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树 不是树
- BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树
题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...
- BZOJ 2959 长跑 (LCT+并查集)
题面:BZOJ传送门 当成有向边做的发现过不去样例,改成无向边就忘了原来的思路.. 因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和 这样保证了图是一颗森林 每次询问转化为, ...
- BZOJ 2959 长跑 (LCT、并查集)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2959 题解 真是被这题搞得心态大崩--调了7个小时--然而并查集都能写成\(O(n^2) ...
- BZOJ 2959: 长跑 LCT_并查集_点双
真tm恶心...... Code: #include<bits/stdc++.h> #define maxn 1000000 using namespace std; void setIO ...
- 【UVA10972】RevolC FaeLoN (求边双联通分量)
题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...
- lightoj 1300 边双联通分量+交叉染色求奇圈
题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...
- HDU5409---CRB and Graph 2015多校 双联通分量缩点
题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...
- poj2942(双联通分量,交叉染色判二分图)
题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 思路:首先 ...
随机推荐
- halcon发布
1: halcon发布 : 在MFC程序中 添加 #include "include/halcon/cpp/HalconCpp.h"using namespace Halcon;# ...
- 【Eclipse】eclipse生成类图、类交互图、包依赖图
今天,在修改毕设论文的时候需要画类图,系统已经开发完成,如果手动拿PowerDesigner画类图太浪费时间,于是通过网上查阅资料发现eclipse可以集成一个插件生成类图,也可以生成包图.现在做记录 ...
- bzoj 1014: 洛谷 P4036: [JSOI2008]火星人
题目传送门:洛谷P4036. 题意简述: 有一个字符串,支持插入字符,修改字符. 每次需要查询两个后缀的LCP长度. 最终字符串长度\(\le 100,\!000\),修改和询问的总个数\(\le 1 ...
- 【CTF WEB】GCTF-2017读文件
读文件 只给了个1.txt可以读,试了一下加*不行,感觉不是命令执行,"../"返回上级目录也不行,猜测可能过滤了什么,在1.txt中间加上"./"发现仍能读取 ...
- Floyd_Warshall算法
Floyd_Warshall算法主要用于求解所有节点对的最短路径,代码如下: #include<iostream> using namespace std; #define Inf 655 ...
- Word Ladder I & II
Word Ladder I Given two words (start and end), and a dictionary, find the length of shortest transfo ...
- LVS ARP广播产生的问题和处理方式【转】
转自 LVS ARP广播产生的问题和处理方式-htckiller2010-ChinaUnix博客http://blog.chinaunix.net/uid-24960107-id-193084.htm ...
- Windows Phone 8 获取设备名称
通过使用Microsoft.Phone.Info.DeviceStatus类,我们可以获取设备的一些信息,如设备厂商,设备名称等.通过Microsoft.Phone.Info.DeviceStatus ...
- Vue.js 基础快速入门
Vue.js是一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.Vue.js提供了简洁.易于理解的API,使得我们能够快速地上手并使用Vue.js 如果之前已经习惯了用jQue ...
- KVM和远程管理工具virt-manager
kvm在server端的部署(针对rhel6系统,可以构建本地更新源) 注意:如果只是安装管理工具,可以试试直接执行8步骤 1.对服务器实行kvm虚拟化首先需要确认服务器的物理硬件是否支持 cat / ...