zoukankan      html  css  js  c++  java
  • bzoj4025: 二分图 lct

    题意:带增删边的查询二分图
    题解:因为二分图肯定带奇环,lct维护,每次要加入一条边之前判断会不会构成环,如果会就把最先会删除的边删掉,然后如果是奇环就打个标记,然后把奇环数++,删除的时候,把标记删除,然后奇环数量--,需要注意的是可能有自环,还有一点就是我们先把边拆成点了,判断奇环的时候不能直接看是奇数还是偶数,我们先/2再看是不是奇数,如果/2是偶数就是有奇环

    /**************************************************************
        Problem: 4025
        User: walfy
        Language: C++
        Result: Accepted
        Time:11120 ms
        Memory:45776 kb
    ****************************************************************/
     
    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    //#define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    template<typename T>
    inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>
    inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
     
    using namespace std;
     
    const double eps=1e-8;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=500000+10,maxn=100000+10,inf=0x3f3f3f3f;
     
    struct LCT{
        int fa[N],ch[N][2],rev[N],sz[N],q[N],odd[N],ti[N],id[N],mi[N];
        void init()
        {
            memset(ch,0,sizeof ch);
            memset(fa,0,sizeof fa);
            memset(sz,0,sizeof sz);
            memset(rev,0,sizeof rev);
        }
        inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
        inline void pushup(int x)
        {
            sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
            mi[x]=ti[x];id[x]=x;
            if(ch[x][0]&&mi[x]>mi[ch[x][0]])
            {
                mi[x]=mi[ch[x][0]];
                id[x]=id[ch[x][0]];
            }
            if(ch[x][1]&&mi[x]>mi[ch[x][1]])
            {
                mi[x]=mi[ch[x][1]];
                id[x]=id[ch[x][1]];
            }
        }
        inline void pushdown(int x)
        {
            if(rev[x])
            {
                rev[x]=0;swap(ch[x][0],ch[x][1]);
                rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
            }
        }
        inline void Rotate(int x)
        {
            int y=fa[x],z=fa[y],l,r;
            if(ch[y][0]==x)l=0,r=l^1;
            else l=1,r=l^1;
            if(!isroot(y))
            {
                if(ch[z][0]==y)ch[z][0]=x;
                else ch[z][1]=x;
            }
            fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
            ch[y][l]=ch[x][r];ch[x][r]=y;
            pushup(y);
        }
        inline void splay(int x)
        {
            int top=1;q[top]=x;
            for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
            for(int i=top;i;i--)pushdown(q[i]);
            while(!isroot(x))
            {
                int y=fa[x],z=fa[y];
                if(!isroot(y))
                {
                    if((ch[y][0]==x)^(ch[z][0]==y))Rotate(x);
                    else Rotate(y);
                }
                Rotate(x);
            }
            pushup(x);
        }
        inline void access(int x){for(int y=0;x;y=x,x=fa[x])splay(x),ch[x][1]=y,pushup(x);}
        inline void makeroot(int x){access(x),splay(x),rev[x]^=1;}
        inline int findroot(int x){access(x),splay(x);while(ch[x][0])x=ch[x][0];return x;}
        inline void split(int x,int y){makeroot(x),access(y),splay(y);}
        inline void cut(int x,int y){split(x,y);if(ch[y][0]==x)ch[y][0]=0,fa[x]=0;}
        inline void link(int x,int y){makeroot(x),fa[x]=y,splay(x);}
    }lct;
    struct node{int u,v,st,en,id;}p[N];
    vi s[N],e[N];
    int main()
    {
    //    fin;
        int n,m,T;
        scanf("%d%d%d",&n,&m,&T);
        for(int i=1;i<=n;i++)lct.ti[i]=lct.mi[i]=inf,lct.id[i]=i,lct.sz[i]=1;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&p[i].u,&p[i].v,&p[i].st,&p[i].en);
            p[i].id=i+n;
            s[p[i].st].pb(i),e[p[i].en].pb(i);
            lct.ti[i+n]=lct.mi[i+n]=p[i].en;lct.id[i+n]=i+n;lct.sz[i+n]=1;
        }
        int o=0,f=0;
        for(int i=0;i<=T;i++)
        {
            if(i)puts(o?"No":"Yes");
    //        printf("%d %d
    ",i,o);
            for(int j=0;j<s[i].size();j++)
            {
                node te=p[s[i][j]];
                if(te.u==te.v)
                {
                    lct.odd[te.id]=1,o++;
                    continue;
                }
                int x=lct.findroot(te.u),y=lct.findroot(te.v);
                if(x!=y)lct.link(te.u,te.id),lct.link(te.v,te.id);
                else
                {
                    lct.split(te.u,te.v);
                    int k=lct.id[te.v]-n;
                    if(lct.mi[te.v]>te.en)
                    {
                        if((lct.sz[te.v]/2)%2==0)lct.odd[te.id]=1,o++;
                        continue;
                    }
                    if((lct.sz[te.v]/2)%2==0)lct.odd[k+n]=1,o++;
                    lct.cut(p[k].u,p[k].id),lct.cut(p[k].v,p[k].id);
                    lct.link(te.u,te.id),lct.link(te.v,te.id);
                }
            }
            for(int j=0;j<e[i].size();j++)
            {
                node te=p[e[i][j]];
                if(te.u==te.v)
                {
                    o-=lct.odd[te.id];
                    lct.odd[te.id]=0;
                    continue;
                }
                int x=lct.findroot(te.u),y=lct.findroot(te.v);
                if(x!=y)o-=lct.odd[te.id],lct.odd[te.id]=0;
                else
                {
                    lct.split(te.u,te.v);
    //                if((lct.sz[te.v]/2)%2==0)
                        o-=lct.odd[te.id],lct.odd[te.id]=0;
                    int k=lct.id[te.v]-n;
                    lct.cut(p[k].u,p[k].id),lct.cut(p[k].v,p[k].id);
                }
            }
        }
        return 0;
    }
    /********************
    3 3 5
    1 2 0 5
    2 3 0 4
    1 1 1 3
    ********************/
    
  • 相关阅读:
    bzoj 4539 [Hnoi2016]树——主席树+倍增
    bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树
    bzoj 4025 二分图——线段树分治+LCT
    LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治
    bzoj 3572 [Hnoi2014]世界树——虚树
    bzoj 4650(洛谷 1117) [Noi2016]优秀的拆分——枚举长度的关键点+后缀数组
    洛谷 P3957 跳房子 —— 二分答案+单调队列优化DP
    洛谷 P1578 奶牛浴场 —— 最大子矩形
    bzoj 1510 Kra-The Disks —— 思路
    bzoj 1657 Mooo 奶牛的歌声 —— 单调栈
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9516239.html
Copyright © 2011-2022 走看看