【BZOJ4025】—二分图(线段树分治+带权并查集)

传送门

线段树分治水题

带权并查集维护一下到根的奇偶行就可以了

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
	char ch=gc();
	int res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define pob pop_back
#define cs const
#define poly vector<int>
#define db double
#define bg begin
cs int mod=1004535809,G=3;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline void Add(int &a,int b){a=add(a,b);}
inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
inline void Dec(int &a,int b){a=dec(a,b);}
inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=400005;
vector<pii> e[N];
vector<pii> p[N];
int n,m,tt;
#define lc (u<<1)
#define rc ((u<<1)|1)
#define mid ((l+r)>>1)
int fa[N],siz[N],col[N],ans[N];
void update(int u,int l,int r,int st,int des,pii p){
	if(st<=l&&r<=des){e[u].pb(p);return;}
	if(st<=mid)update(lc,l,mid,st,des,p);
	if(mid<des)update(rc,mid+1,r,st,des,p);
}
inline int find(int &x){
	int c=0;
	while(x!=fa[x])c^=col[x],x=fa[x];
	return c;
}
void dfs(int u,int l,int r){
	int flag=0;
	for(pii &x:e[u]){
		int a=x.fi,b=x.se;
		int f1=find(a),f2=find(b);
		if(a==b){
			if(f1==f2){
				flag=1;
				for(int i=l;i<=r;i++)ans[i]=0;
				break;
			}
		}
		else{
			if(siz[a]<siz[b])swap(a,b);
			fa[b]=a,col[b]=f1^f2^1,siz[a]+=siz[b];
			p[u].pb(pii(a,b));
		}
	}
	if(!flag&&l!=r)dfs(lc,l,mid),dfs(rc,mid+1,r);
	for(pii &x:p[u]){
		fa[x.se]=x.se,col[x.se]=0,siz[x.fi]-=siz[x.se];
	}
}
int main(){
	n=read(),m=read(),tt=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read(),l=read()+1,r=read()+1;
		if(l<r)update(1,1,tt,l,r-1,pii(u,v));
	}
	for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;
	for(int i=1;i<=tt;i++)ans[i]=1;
	dfs(1,1,tt);
	for(int i=1;i<=tt;i++)cout<<(ans[i]?"Yes":"No")<<'\n';
}
posted @ 2019-08-30 21:35  Stargazer_cykoi  阅读(84)  评论(0编辑  收藏  举报