线段树分治爆零求助
查看原帖
线段树分治爆零求助
275860
___A__楼主2024/7/23 15:16
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,k,ans[N],p[N*2],siz[N*2];
vector<pair<int,int>>vec[N*4];
void update(int u,int x,int y,int l,int r,int L,int R){
	if(L>=l&&R<=r){
		vec[u].push_back({x,y});
		return;
	}
	int mid=(L+R)>>1;
	if(l<=mid){
		update(u*2,x,y,l,r,L,mid);
	}
	if(r>mid){
		update(u*2+1,x,y,l,r,mid+1,R);
	}
}
int find(int x){
	if(p[x]==x){
		return x;
	}
	return find(p[x]);
}
struct status{
	int fx,fy,sizfy;
};
stack<status>ware;
void merge(int x,int y){
	if(siz[y]>siz[x]){
		merge(y,x);
		return;
	} 
	int fx=find(x),fy=find(y);
	siz[fx]+=siz[fy],p[fy]=fx,ware.push({fx,fy,siz[fy]});
}
void del(){
	while(ware.size()){
		auto [fx,fy,sizfy]=ware.top();
		ware.pop(),p[fy]=fy,siz[fx]-=sizfy;
	}
}
void solve(int u,int l,int r,int now){
	for(auto [x,y]:vec[u]){
		merge(x,y+n),merge(x+n,y);
        if(find(x)==find(x+n)||find(y)==find(y+n)){
            now=1;
        }
	}
	if(l==r){
		ans[l]=now,del();
		return;
	}
	int mid=(l+r)>>1;
	solve(u*2,l,mid,now),solve(u*2+1,mid+1,r,now),del();
}
int main(){
	cin>>n>>m>>k;
	for(int x,y,l,r;m--;){
		cin>>x>>y>>l>>r,update(1,x,y,l,r,0,k);
	}
	for(int i=1;i<=2*n;i++){
		p[i]=i,siz[i]=1;
	}
	solve(1,0,k,0);
	for(int i=0;i<=k;i++){
		if(!ans[i]){
			cout<<"Yes\n";
		}
		else{
			cout<<"No\n";
		}
	}
}
2024/7/23 15:16
加载中...