10分,求助
查看原帖
10分,求助
204935
hexagon楼主2021/1/27 20:00

第一次写线段树分治

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a),i##end=(b);i<=i##end;i++)
#define per(i,a,b) for(int i=(a),i##end=(b);i>=i##end;i--)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=800005;
int n,m,k,fa[2*N],siz[2*N],st;
struct node{
	int a,b,c;
}s[N];
struct T{
	int l,r;
	vector <pair<int,int> > v;
}t[N<<2];
inline int findfa(int x) {while(x^fa[x]) x=fa[x];return x;}
inline void unionn(int x,int y){
	if(x==y) return;
	if(siz[x]<siz[y]) swap(x,y);
	s[++st]=node{x,y,siz[y]},siz[x]+=siz[y],fa[y]=x;
}
inline void undo(){
	int a=s[st].a,b=s[st].b,c=s[st].c;
	st--;
	fa[b]=b,siz[a]-=c;
}
inline int read(){
	int f=1,x=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
	return f*x;
}
inline void build(int rt,int l,int r){
	t[rt].l=l,t[rt].r=r;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
}
inline void add(int rt,int l,int r,int x,int y){
	if(l<=t[rt].l&&t[rt].r<=r) return t[rt].v.push_back(make_pair(x,y)),void();
	if(t[rt<<1].r>=l) add(rt<<1,l,r,x,y);
	if(t[rt<<1|1].l<=r) add(rt<<1|1,l,r,x,y);
}
inline void dfs(int rt){
	int tmp=st,flag=0;
	for(auto u:t[rt].v){
		int a=u.first,b=u.second;
		if(findfa(a+n)==findfa(b+n)||findfa(b)==findfa(a)){
			rep(i,t[rt].l,t[rt].r) printf("No\n");
			flag=1;
			break;
		}
		unionn(findfa(a),findfa(b+n));
		unionn(findfa(b),findfa(a+n));
	}
	if(flag==0){
		if(t[rt].l==t[rt].r) printf("Yes\n");
		else{
			dfs(rt<<1);
			dfs(rt<<1|1);
		}
	}
	while(st>tmp) undo();
}
int main(){
	n=read(),m=read(),k=read();
	rep(i,1,2*n) fa[i]=i;
	build(1,1,k);
	rep(i,1,n){
		int x=read(),y=read(),z=read(),w=read();
		if(z==w) continue;
		add(1,z+1,w,x,y);
	}
	dfs(1);
	return 0;
}
2021/1/27 20:00
加载中...