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

题意

sol.线段树分治板子 + 可撤销并查集按秩合并

#include<bits/stdc++.h>
#define MAXN 400005
using namespace std;

int n,m,k,ans[MAXN];
int fa[MAXN],sz[MAXN],dis[MAXN];
vector< pair<int , int> >vec[MAXN * 4];

int found(int x){
	if(fa[x] == x){
		dis[x] = 0;
		return x;	
	}
	int zz = found(fa[x]);
	return zz;
}

void update(int rt , int l , int r , int x , int y , pair<int , int> v){
	if(r < x || l > y)return;
	if(x <= l && r <= y)return (void)(vec[rt].push_back(v));
	int mid = (l + r) >> 1;
	update(rt << 1 , l , mid , x  , y , v);
	update(rt << 1 | 1 , mid + 1 , r , x  , y , v);
}

void que(int rt , int l , int r){
	int mid = (l + r) >> 1;
	int fx,fy,x,y;
	int judge = 0;
	stack< pair<int , int> >q;
	while(!q.empty())q.pop();
	for(int i = 0 ; i < vec[rt].size() ; i++){
		x = vec[rt][i].first , y = vec[rt][i].second;
		fx = found(x) , fy = found(y);
		if(fx == fy && dis[x] == dis[y])judge = 1;//撤销之前的操作 
		else if(fx != fy){
			fa[fx] = fy , dis[fx] = dis[y] ^ 1 , sz[fy] += sz[fx];
			q.push(make_pair(fx , fy));
		}
	}
	
	if(!judge){
		if(l == r)return (void)(ans[l] = 1);
		que(rt << 1 , l , mid);
		que(rt << 1 | 1 , mid + 1 , r);	
	}
	pair<int , int>now;
	while(!q.empty()){
		now = q.top() , q.pop();
		sz[now.second] -= sz[now.first];
		fa[now.first] = now.first;
	}
	
}

int main(){
	scanf("%d%d%d" , &n , &m , &k);
	for(int i = 1 ; i <= n ; i++)fa[i] = i , sz[i] = 1 , dis[i] = 0;
	int x,y,l,r;
	while(m--){
		scanf("%d%d%d%d" , &x , &y , &l , &r);
		l++;
		update(1 , 1 , k , l , r , make_pair(x , y));
	}
	que(1 , 1 , k);
	for(int i = 1 ; i <= k ; i++){
		if(ans[i])cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}
posted @ 2021-11-06 16:35  After_rain  阅读(54)  评论(0)    收藏  举报