zoukankan      html  css  js  c++  java
  • bzoj3237: [Ahoi2013]连通图

    上线段树分治

    它删除的边的总数不会很大,我们可以维护一条边在那一段时间里面是存在的

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    using namespace std;
    
    struct edge{int x,y;}e[410000];
    
    struct trnode
    {
        int l,r,lc,rc;
        vector<int>id;
    }tr[410000];int trlen;
    void bt(int l,int r)
    {
        int now=++trlen;
        tr[now].l=l;tr[now].r=r;
        tr[now].lc=tr[now].rc=-1;
        if(l<r)
        {
            int mid=(l+r)/2;
            tr[now].lc=trlen+1;bt(l,mid);
            tr[now].rc=trlen+1;bt(mid+1,r);
        }
    }
    void change(int now,int l,int r,int p)
    {
        if(tr[now].l==l&&tr[now].r==r)
        {
            tr[now].id.push_back(p);
            return ;
        }
        int mid=(tr[now].l+tr[now].r)/2;
        int lc=tr[now].lc,rc=tr[now].rc;
               if(r<=mid)  change(lc,l,r,p);
        else if(mid+1<=l)change(rc,l,r,p);
        else change(lc,l,mid,p),change(rc,mid+1,r,p);
    }
    
    int n,cnt,fa[410000];
    int findfa(int x)
    {
        if(fa[x]<0)return x;
        return findfa(fa[x]);
    }
    struct Clear
    {
        int fx,fy,dx,dy,id;
        Clear(){}
        Clear(int FX,int FY,int DX,int DY,int ID){fx=FX,fy=FY,dx=DX,dy=DY,id=ID;}
    }sta[410000];int top;
    void merge(int now,int x,int y)
    {
        int fx=findfa(x),fy=findfa(y);
        if(fx!=fy)
        {
            cnt++;
            sta[++top]=Clear(fx,fy,fa[fx],fa[fy],now);
            if(fa[fx]<fa[fy])
                fa[fx]+=fa[fy],fa[fy]=fx;
            else
                fa[fy]+=fa[fx],fa[fx]=fy;
        }
    }
    void sprit(int p)
    {
        cnt--;
        fa[sta[p].fx]=sta[p].dx;
        fa[sta[p].fy]=sta[p].dy;
    }
    
    bool as[410000];
    void dfs(int now)
    {
        for(int i=0;i<tr[now].id.size();i++)
            merge(now,e[tr[now].id[i]].x,e[tr[now].id[i]].y);
            
        if(cnt==n-1)
        {
            for(int i=tr[now].l;i<=tr[now].r;i++)as[i]=true;
        }
        else if(tr[now].l==tr[now].r);
        else
        {
            dfs(tr[now].lc);
            dfs(tr[now].rc);
        }
        
        while(sta[top].id==now)
            sprit(top--);
    }
    
    int las[410000];
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int m,x,y;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
            scanf("%d%d",&e[i].x,&e[i].y);
        
        for(int i=1;i<=m;i++)las[i]=1;
        int Q,S;
        scanf("%d",&Q);
        trlen=0;bt(1,Q);
        for(int q=1;q<=Q;q++)
        {
            scanf("%d",&S);
            for(int i=1;i<=S;i++)
            {
                scanf("%d",&x);
                if(las[x]<=q-1)
                {
                    change(1,las[x],q-1,x);
                //    printf("%d %d %d
    ",x,las[x],q-1);
                }
                las[x]=q+1;
            }
        }
        for(int i=1;i<=m;i++)
            if(las[i]<=Q)
            {
                change(1,las[i],Q,i);
            //    printf("%d %d %d
    ",i,las[i],Q);
            }
            
        for(int i=1;i<=m;i++)fa[i]=-1;
        cnt=top=0;dfs(1);
        for(int i=1;i<=Q;i++)
            if(as[i])printf("Connected
    ");
            else printf("Disconnected
    ");
                
        return 0;
    }
  • 相关阅读:
    Google-C++编码规范中文版.pdf
    100个gdb小技巧(v1.0).pdf
    NSIS 3.0 发布,Windows 安装程序制作工具
    python爬取各类文档方法归类汇总
    【转】openwrt中ubus
    OpenWrt源码分析之ubus
    详解C语言中的fopen()函数和fdopen()函数
    IPsec技术介绍(转)
    mxml 详解
    Delphi IDE Theme Editor, Delphi IDE 主题编辑器,支持D7~Rad Studio 10.3 RIO及Lazarus
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10212233.html
Copyright © 2011-2022 走看看