[loj#121][线段树分治][并查集]动态图连通性

版权声明:蒻蒟的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;
}

猜你喜欢

转载自blog.csdn.net/Rose_max/article/details/85242138