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的更多相关文章

  1. BZOJ 2959: 长跑 [lct 双连通分量 并查集]

    2959: 长跑 题意:字词加入边,修改点权,询问两点间走一条路径的最大点权和.不一定是树 不是树

  2. BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树

    题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...

  3. BZOJ 2959 长跑 (LCT+并查集)

    题面:BZOJ传送门 当成有向边做的发现过不去样例,改成无向边就忘了原来的思路.. 因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和 这样保证了图是一颗森林 每次询问转化为, ...

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

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

  5. BZOJ 2959: 长跑 LCT_并查集_点双

    真tm恶心...... Code: #include<bits/stdc++.h> #define maxn 1000000 using namespace std; void setIO ...

  6. 【UVA10972】RevolC FaeLoN (求边双联通分量)

    题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...

  7. lightoj 1300 边双联通分量+交叉染色求奇圈

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...

  8. HDU5409---CRB and Graph 2015多校 双联通分量缩点

    题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...

  9. poj2942(双联通分量,交叉染色判二分图)

    题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 思路:首先 ...

随机推荐

  1. cmake设置默认静态链接库

    在使用cmake来编写CMakeLists.txt时,如果不特别指明,那么cmake是默认动态链接库的,最终生成的二进制文件只能在与本地相同环境下的机器运行,如果想把生成的二进制拷贝到其他机器上执行, ...

  2. Java设计模式——工厂模式

    一.工厂模式分类 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: (1)简单工厂模式(Simp ...

  3. 【codeforces】【比赛题解】#854 CF Round #433 (Div.2)

    cf一如既往挺丧 看丧题点我! [A]分数 Petya是数学迷,特别是有关于分数的数学.最近他学了所谓一个分数被叫做“真分数”当且仅当其分子小于分母,而一个分数被叫做“最简分数”当且仅当其分子分母互质 ...

  4. Linux学习笔记-Linux系统简介

    Linux学习笔记-Linux系统简介 UNIX与Linux发展史 UNIX是父亲,Linux是儿子. UNIX发行版本 操作系统 公司 硬件平台 AIX IBM PowerPC HP-UX HP P ...

  5. java 判断上传文件大小

    /** * 判断文件大小 * * @param file * 文件 * @param size * 限制大小 * @param unit * 限制单位(B,K,M,G) * @return */ pu ...

  6. haproxy支持的负载均衡算法详解

    目前haproxy支持的负载均衡算法有如下8种: 1.roundrobin 表示简单的轮询,每个服务器根据权重轮流使用,在服务器的处理时间平均分配的情况下这是最流畅和公平的算法.该算法是动态的,对于实 ...

  7. 数据库-mysql安装

    MySQL 安装 所有平台的Mysql下载地址为: MySQL 下载. 挑选你需要的 MySQL Community Server 版本及对应的平台. Linux/UNIX上安装Mysql Linux ...

  8. python logging 日志

    logging与print 区别,为什么需要logging? 在写脚本的过程中,为了调试程序,我们往往会写很多print打印输出以便用于验证,验证正确后往往会注释掉,一旦验证的地方比较多,再一一注释比 ...

  9. python+selenium第一步 - 环境搭建

    刚开始学习一门技术,肯定是要从环境搭建开始的,我也不例外. 首先选择需要安装的版本,我使用的是mac自带的2.7版本. selenium2,和火狐浏览器 为求稳定不会出现未知问题,我选择了seleni ...

  10. MySQL学习笔记:三种组内排序方法

    由于MySQ没有提供像Oracle的dense_rank()或者row_number() over(partition by)等函数,来实现组内排序,想实现这个功能,还是得自己想想办法,最终通过创建行 ...