[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;
}

猜你喜欢

转载自www.cnblogs.com/cjfdf/p/9386007.html