#2783 【离线可过】动态图连通性【模板】
题面
你要维护一张无向简单图。你被要求加入删除一条边及查询两个点是否连通。
0:加入一条边。保证它不存在。
1:删除一条边。保证它存在。
2:查询两个点是否联通。
输入
输入的第一行是两个数 N M。N≤5000,M≤500000。
接下来 M 行,每一行三个数 op x y。op 表示操作编号。
样例输入
200 5
2 123 127
0 123 127
2 123 127
1 127 123
2 123 127
样例输出
N
Y
N
数据规模与约定
对于数据点 1,N≤200,M≤200
对于数据点 2,N=5,M≤30
对于数据点 3,N=10,M≤1000,其中查询的次数 ≥900次。
对于数据点 4,N=300,M≤50000
对于数据点 5,N=5000,M≤200000,没有操作 1,其中约 70% 是操作 2。
对于数据点 6,N=5000,M≤200000,没有操作 1,其中约 70%是操作 0。
对于数据点 7、8,N=100,M≤500000
对于数据点 9,N=5000,M≤500000,图是一棵树,其直径 ≤6 。
对于数据点 10, N=5000,M≤500000,图是一棵树,其每个点度数 ≤4 。
P.S. 其实 9 是菊花,10 是单链,而没有放随机树的点…
SOL
显然按操作时间建权值线段树
将每条边在[l,r]时间区间插入线段树即可
离线处理每次询问,递归查询到叶子结点时处理答案
并查集按秩合并,由于做完之后要撤销,不能压缩路径
代码:
#include<bits/stdc++.h>
using namespace std;
#define re register
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
int re data=0;static char ch=0;ch=nc();
while(!isdigit(ch))ch=nc();
while(isdigit(ch))data=(data<<1)+(data<<3)+(ch^48),ch=nc();
return data;
}
const int N=5001,M=500001;
int tot,P[M],top,p1[N