[BZOJ4025]二分图

description

题面

solution

这里的单点询问需要全部的修改才能统计出答案

需要用到线段树分治的另一个形式:
在树上\(DFS\)维护数据结构,进入叶子的时候求出询问答案,回溯的时候栈序撤销

数据结构选择的是并查集,维护连通性和到达代表元(根节点)的路径长度奇偶性,合并的时候判断是否出现奇环即可

写了一个比较直接的内存修改的撤销
空间227M
千万别学我

code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=2e5+10;
const dd pi=acos(-1);
const int inf=2147483647;
const ll INF=1e18+1;
il ll read(){
	RG ll data=0,w=1;RG char ch=getchar();
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
	return data*w;
}

int n,m,T;
struct modify{int u,v;}M[N];vector<modify>f[N<<4];
struct data{int o,id,x;};vector<data>g[N<<4];
#define mid ((l+r)>>1)
#define ls (t<<1)
#define rs (t<<1|1)
void insertmodify(int t,int l,int r,int x,int y,modify m){
	if(x<=l&&r<=y){f[t].pb(m);return;}
	if(x<=mid)insertmodify(ls,l,mid,x,y,m);
	if(mid<y)insertmodify(rs,mid+1,r,x,y,m);
}

int fa[N],sz[N],dis[N],now;
int find(int x){
	if(fa[x]==x)return x;
	RG int ff=find(fa[x]);
	if(dis[fa[x]]){
		g[now].pb((data){3,x,dis[x]});
		dis[x]^=1;
	}
	if(fa[x]!=ff){
		g[now].pb((data){1,x,fa[x]});
		fa[x]=ff;
	}
	return fa[x];
il bool merge(int u,int v){
	RG int fu=find(u),fv=find(v);
	if(fu==fv)return dis[u]^dis[v];
	if(sz[fu]>sz[fv])swap(u,v),swap(fu,fv);
	g[now].pb((data){1,fu,fa[fu]});
	fa[fu]=fv;
	g[now].pb((data){2,fv,sz[fv]});
	sz[fv]+=sz[fu];
	g[now].pb((data){3,fu,dis[fu]});
	dis[fu]=dis[u]^dis[v]^1;
	return 1;
}
il void recover(int t){
	while(g[t].size()){
		RG data a=g[t][g[t].size()-1];
		if(a.o==1)fa[a.id]=a.x;
		if(a.o==2)sz[a.id]=a.x;
		if(a.o==3)dis[a.id]=a.x;
		g[t].pop_back();
	}
}
void segdiv(int t,int l,int r){
	now=t;
	for(RG int i=0,sz=f[t].size();i<sz;i++)
		if(!merge(f[t][i].u,f[t][i].v)){
			for(RG int j=l;j<=r;j++)puts("No");
			recover(t);
			return;
		}
	if(l==r){puts("Yes");recover(t);return;}
	segdiv(ls,l,mid);segdiv(rs,mid+1,r);
	recover(t);
}

int main()
{
	n=read();m=read();T=read();
	for(RG int i=1;i<=n;i++)fa[i]=i,sz[i]=1,dis[i]=0;
	for(RG int i=1,l,r;i<=m;i++){
		M[i].u=read();M[i].v=read();
		l=read()+1;r=read();
		insertmodify(1,1,T,l,r,M[i]);
	}
	segdiv(1,1,T);
	return 0;
}

posted @ 2018-07-29 17:20  cjfdf  阅读(115)  评论(0编辑  收藏  举报