二分图 /【模板】线段树分治

  • 回溯不要有遗漏,一一对应修改
#include <bits/stdc++.h>
using namespace std;
bool ans[100005];
typedef pair<int,int> pii;
struct t1
{
	int l,r;
	vector<pii>v;
}t[400005];
void build(int p,int l,int r)
{
	t[p].l=l;
	t[p].r=r;
	if(l==r)
	{
		return;
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
}
void change(int p,int l,int r,int u,int v)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		t[p].v.push_back(pii(u,v));
		return;
	}
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid)
	{
		change(p*2,l,r,u,v);
	}
	if(r>mid)
	{
		change(p*2+1,l,r,u,v);
	}
}
int fa[200005],tot,n,m,k;
bool f=true;
int get(int x)
{
	if(fa[x]==x)
	{
		return x;
	}
	return get(fa[x]);
}
void solve(int p)
{
	stack<pii>y;
	bool tmp=f;
	int Tmp=tot;
	for(auto x:t[p].v)
	{
		int u=x.first,v=x.second;
		int U=get(u),V=get(v);
		if(U==V)
		{
			f=false;
		}
		else if(U<=n&&V<=n)
		{
			y.push(pii(u,fa[u]));
			y.push(pii(v,fa[v]));
			fa[u]=tot;
			fa[v]=tot+1;
			tot+=2;
		}
		else if(U<=n&&V>n)
		{
			y.push(pii(u,fa[u]));
			fa[u]=get(V^1);
		}
		else if(U>n&&V<=n)
		{
			y.push(pii(v,fa[v]));
			fa[v]=get(U^1);
		}
		else
		{
			y.push(pii(U,fa[U]));
			y.push(pii(V,fa[V]));
			fa[U]=get(V^1);
			fa[V]=get(U^1);
		}
	}
	if(t[p].l==t[p].r)
	{	
		ans[t[p].l]=f;
	}
	else
	{
		solve(p*2);
		solve(p*2+1);
	}
	while(y.size())
	{
		pii x=y.top();
		int u=x.first,v=x.second;
		fa[u]=v;
		y.pop();
	}
	tot=Tmp;
	f=tmp;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m>>k;
	build(1,0,k);
	for(int i=1;i<=m;i++)
	{
		int x,y,l,r;
		cin>>x>>y>>l>>r;
		change(1,l,r-1,x,y);
	}
	tot=(n+1)+(n%2==0);
	for(int i=1;i<=2*n+1;i++)
	{
		fa[i]=i;
	}
	solve(1);
	for(int i=0;i<k;i++)
	{
		ans[i]? cout<<"Yes\n":cout<<"No\n";
	}
	return 0;
}
posted @ 2025-02-18 16:58  D06  阅读(6)  评论(0)    收藏  举报
//雪花飘落效果