版权声明:蒻蒟的bolg... https://blog.csdn.net/Rose_max/article/details/85242138
Description
动态加边删边维护图连通性
n<=5000,m<=500000
允许离线
题解
wori这种模板都不会写了吗…
预处理每条边在什么时候出现什么时候消失
根据时间建线段树
线段树每个节点开一个vector存在他管理这段时间里一直存在的边
把边一开始插入就可以知道这个线段树长什么样了
然后开始线段树分治,dfs这棵线段树
进去的时候就把边全部插入出来就全部删除
由于加入和删除的边是连续一段的所以可以兹瓷
并查集按秩合并一下…
扫到叶子节点就回答询问
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
#define lc now<<1
#define rc now<<1|1
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int stack[20];
inline void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);putchar('\n');}
const int MAXN=5005;
const int MAXM=500005;
struct edge{int x,y,S,T;}E[MAXM];int len;
vector<int> vec[MAXM*4];
int n,m;
void modify(int now,int l,int r,int ql,int qr,int op)
{
if(l==ql&&r==qr){vec[now].push_back(op);return ;}
int mid=(l+r)/2;
if(qr<=mid)modify(lc,l,mid,ql,qr,op);
else if(mid+1<=ql)modify(rc,mid+1,r,ql,qr,op);
else modify(lc,l,mid,ql,mid,op),modify(rc,mid+1,r,mid+1,qr,op);
}
struct node
{
int r1,r2;
node(){}
node(int _r1,int _r2){r1=_r1;r2=_r2;}
}sta[MAXM],ask[MAXM];int tp,sta1[MAXM],tp1;
int fa[MAXN],tot[MAXN];
int findfa(int x){return fa[x]==x?x:findfa(fa[x]);}
void in(int now)
{
for(int j=0;j<vec[now].size();j++)
{
int u=vec[now][j];
int p=findfa(E[u].x),q=findfa(E[u].y);
if(p!=q)
{
if(tot[p]>tot[q])swap(p,q);
sta[++tp]=node(p,q);
fa[p]=q;tot[q]+=tot[p];
}
}
sta1[++tp1]=tp;
}
void re()
{
tp1--;
while(tp!=sta1[tp1])
{
int p=sta[tp].r1,q=sta[tp].r2;
fa[p]=p;tot[q]-=tot[p];tp--;
}
}
void work(int tim)
{
if(!ask[tim].r1)return ;
int p=findfa(ask[tim].r1),q=findfa(ask[tim].r2);
if(p==q)puts("Y");
else puts("N");
}
void query(int now,int l,int r)
{
in(now);
if(l==r)
{
work(l);
re();return ;
}
int mid=(l+r)/2;
query(lc,l,mid);
query(rc,mid+1,r);
re();
}
int mp[MAXN][MAXN];
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)fa[i]=i,tot[i]=1;
for(int i=1;i<=m;i++)
{
int op=read(),x=read(),y=read();if(x>y)swap(x,y);
if(op==2)ask[i]=node(x,y);
else if(op==0)
{
E[++len].x=x;E[len].y=y;E[len].S=i;
mp[x][y]=len;
}
else E[mp[x][y]].T=i;
}
for(int i=1;i<=len;i++)
{
if(!E[i].T)E[i].T=m;
modify(1,1,m,E[i].S,E[i].T,i);
}
query(1,1,m);
return 0;
}