zoukankan      html  css  js  c++  java
  • [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;
    }
    
    
  • 相关阅读:
    UVA 11235 (游程编码+ST算法)
    CodeForces 359D (数论+二分+ST算法)
    线性动态规划
    AC自动机
    KMP
    字典树
    Treap和名次树
    线段树
    最小生成树
    【VS】使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9386007.html
Copyright © 2011-2022 走看看