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. [转]std::set、自定义类型与比较函数

    转自:http://www.189works.com/article-42025-1.html 怎样在set中放入自定义类型?这个问题通过谷歌就可以得到不少答案:1.定义一个函数对象并在定义set的时 ...

  2. 20165227 实验二《Java面向对象程序设计》实验报告

    2017-2018-4 20165227实验二<Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...

  3. Resouce, platform_device 和 platform_driver 的关系【转】

    转自:http://blog.csdn.net/uruita/article/details/7278313 從2.6版本開始引入了platform這個概念,在開發底層驅動程序時,首先要確認的就是設備 ...

  4. 虚拟机使用主机ss代理

    环境Linux mint 设置好主机ss代理,并开启[允许来自局域网的链接] 在Linux虚拟机的system setting-network手动设置代理 地址全部填入刚刚的主机地址,端口号为主机ss ...

  5. IIS错误:在唯一密钥属性“fileExtension”设置为“.mp4”时,无法添加类型为“mimeMap”的重复集合项

    之前的IIS配置中,.mp4类型的文件默认无法访问,所以个人在IIS7.5的mime类型中增加了.mp4的类型的支持,但问题是需要每台机器中增加这些设置,不利于团队协作,于是,只好将这些修改体现在代码 ...

  6. DevExpress GridControl 的数据绑定

    本人不才啊,折腾2个多小时才把数据绑定好.现在把折腾过程记录一下来以帮助更多的朋友,自己也温习一下. 直接上代码了哈.... WPF哈 xaml文件 <dxg:GridControl Name= ...

  7. Isolate randomforest检测异常点的非监督方法

    由于异常数据的两个特征(少且不同: few and different) 异常数据只占很少量; 异常数据特征值和正常数据差别很大. iTree的构成过程如下: l  随机选择一个属性Attr: l  ...

  8. (二)HtmlUnit 使用

    第一节: htmlunit 模拟浏览器请求 第二节: htmlunit 获取指定元素 第三节: htmlunit 使用代理 IP 第四节: htmlunit 取消 css,javascript 支持 ...

  9. day6面向对象--类的特殊成员方法

    类的特殊成员方法 1. __doc__ 表示类的描述信息 class Func(object): '''__doc__方法是用来打印类的描述信息''' def tell(self): pass def ...

  10. 8-7 Unique Snowflakes UVA11572

    输入一个长度为n n<=10 6  的序列A  找到一个尽量长的连续子序列  使得该序列中没有相同的元素 用滑动窗口法   时间复杂度n  好神奇 此题非常经典 map   410ms #inc ...