萌新刚学二分图求助
查看原帖
萌新刚学二分图求助
209454
watermonster楼主2020/10/30 16:42

RT,刚学线段树分治,太菜了不会带撤销DSU,于是用LCT实现DSU的功能,现在RE30分。

#include <stack>
#include <vector>
#include <cstdio>
#include <utility>
#include <cstring>
#include <algorithm>

using namespace std;

#define il inline
#define re register
#define mp(x,y) make_pair(x,y)

typedef pair<int,int> Pair;

const int N=1e6+10;

namespace FastIO
{
char buf[1<<21],buf2[1<<21],*p1=buf,*p2=buf;
int p,p3=-1;
il int getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
il void flush(){fwrite(buf2,1,p3+1,stdout),p3=-1;}
#define isdigit(ch) (ch>=48&&ch<=57)
template <typename T>
il void read(T &x)
{
	re bool f=0;x=0;
	re char ch=getc();
	while(!isdigit(ch)) f|=(ch=='-'),ch=getc();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getc();
	x=f?-x:x;
}
template <typename T>
il void print(T x)
{
	if(p3>(1<<20)) flush();
	if(x<0) buf2[++p3]=45,x=-x;
	re int a[50]={};
	do{a[++p]=x%10+48;}while(x/=10);
	do{buf2[++p3]=a[p];}while(--p);
}
}
using namespace FastIO;

struct Link_Cut_Tree
{
int fa[N<<1],son[2][N<<1],tag[N<<1];
il void init()
{
	memset(fa,0,sizeof(fa));
	memset(son,0,sizeof(son));
	memset(tag,0,sizeof(tag));
	return;
}
#define ls(x) (son[0][x])
#define rs(x) (son[1][x])
#define indent(x) (rs(fa[x])==x)
#define notrt(x) (ls(fa[x])==x||rs(fa[x])==x)
#define connect(x,f,s) (son[s][f]=x,fa[x]=f)
#define reverse(x) (swap(ls(x),rs(x)),tag[x]^=1)
il void pushdown(int x)
{
	if(!tag[x]) return;
	if(ls(x)) reverse(ls(x));
	if(rs(x)) reverse(rs(x));
	tag[x]^=1;return;
}
il void rotate(int x)
{
	re int f=fa[x],ff=fa[f],k=indent(x);
	connect(son[k^1][x],f,k);
	fa[x]=ff;
	if(notrt(f)) son[indent(f)][ff]=x;
	connect(f,x,k^1);return;
}
int st[N<<2],top;
il void pushall(int x)
{
	top=0;
	while(notrt(x)) st[++top]=x,x=fa[x];
	pushdown(x);
	while(top) pushdown(st[top--]);
	return;
}
il void splay(int x)
{
	pushall(x);
	re int f,ff;
	while(notrt(x))
	{
		f=fa[x];ff=fa[f];
		if(notrt(f)) rotate(indent(x)^indent(f)?x:f);
		rotate(x);
	}
	return;
}
il void access(int x)
{
	for(re int i=0;x;x=fa[i=x])
		splay(x),rs(x)=i;
	return;
}
#define makert(x) (access(x),splay(x),reverse(x))
il int getrt(int x)
{
	access(x);splay(x);
	while(ls(x)) pushdown(x),x=ls(x);
	splay(x);return x;
}
il void link(int x,int y){makert(x);fa[x]=y;return;}
il void cut(int x,int y){makert(x);fa[y]=rs(x)=0;return;}
}LCT;

int n,m,k;

vector<Pair>lz[N<<2];
il void change(int p,int l,int r,int L,int R,int x,int y)
{
	if(l>R||r<L) return;
	if(l>=L&&r<=R){lz[p].push_back(mp(x,y));return;}
	re int mid=(l+r)>>1;
	change(p<<1,l,mid,L,R,x,y);
	change(p<<1|1,mid+1,r,L,R,x,y);
	return;
}
stack<Pair>st;
int top;
il void merge(int x,int y)
{
	re int fx=LCT.getrt(x);
	re int fy=LCT.getrt(y);
	st.push(mp(fx,fy));++top;
	LCT.link(fx,fy);return;
}
il void solve(int p,int l,int r)
{
	re int flag=1,lst=top;
	for(re int i=0,a,b;i<lz[p].size();++i)
	{
		a=LCT.getrt(lz[p][i].first);
		b=LCT.getrt(lz[p][i].second);
		if(a==b)
		{
			for(re int j=l;j<=r;++j) puts("No");
			flag=0;break;
		}
		merge(lz[p][i].first,lz[p][i].second+n);
		merge(lz[p][i].second,lz[p][i].first+n);
	}
	if(flag)
	{
		if(l==r) puts("Yes");
		else
		{
			re int mid=(l+r)>>1;
			solve(p<<1,l,mid);
			solve(p<<1|1,mid+1,r);
		}
	}
	while(top>lst)
	{
		LCT.cut(st.top().first,st.top().second);
		st.pop();--top;
	}
	return;
}

int main()
{
	read(n),read(m),read(k);LCT.init();
	for(re int i=1,x,y,l,r;i<=m;++i)
	{
		read(x),read(y),read(l),read(r);
		change(1,1,k,l+1,r,x,y);
	}
	solve(1,1,k);return 0;
}
2020/10/30 16:42
加载中...