zoukankan      html  css  js  c++  java
  • BZOJ5329 [Sdoi2018]战略游戏 圆方树+虚树

    https://www.lydsy.com/JudgeOnline/problem.php?id=5329

    把仙人掌建成圆方树

    对于每次询问建出一棵虚树

    然后统计两两点对之间的不同圆点个数和

    即为答案

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define re register
    #define rep(i,s,t) for(re int i=s;i<=t;++i)
    using namespace std;
    #define ms(a,x) memset(a,x,sizeof a)
    #define gi(x) read(x)
    #define gii(x,y) read(x),read(y)
    #define giii(x,y,z) read(x),read(y),read(z)
    #define go1(x) for(re int e=G1.las[x];e;e=G1.nxt[e])
    #define go2(x) for(re int e=G2.las[x];e;e=G2.nxt[e])
    namespace IO{
        #define gc getchar()
        #define pc(x) putchar(x)
        template<typename T>inline void read(T &x){
            x=0;int f=1;char ch=gc;while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=gc;}
            while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=gc;x*=f;return;
        }
        template<typename T>inline void write(T x=0){
            T wr[51];wr[0]=0;if(x<0)pc('-'),x=-x;if(!x)pc(48);
            while(x)wr[++wr[0]]=x%10,x/=10;while(wr[0])pc(48+wr[wr[0]--]);return;
        }
    }
    using IO::read;
    using IO::write;
    const int N=4e5+11;
    struct graph{
        int tot;
        int nxt[N],las[N],to[N];
        graph(){
            tot=0,ms(nxt,0),ms(las,0),ms(to,0);
        }
        inline void clear(){
            tot=0,ms(nxt,0),ms(las,0),ms(to,0);
        }
        inline void add(int x,int y){
            nxt[++tot]=las[x];
            las[x]=tot;
            to[tot]=y;
        }
        inline void adde(int x,int y){
            add(x,y),add(y,x);
        }
    }G1,G2;
    int T,n,m,x,y,dfc,tot;
    int low[N],dfn[N],st[N],dis[N],fa[N],
        sz[N],son[N],dep[N],top[N],a[N];
    inline void tarjan(int x,int anc){
        re int v;
        low[x]=dfn[x]=++dfc;
        st[++st[0]]=x;
        go1(x){
            v=G1.to[e];
            if(v==anc)continue;
            if(!dfn[v]){
                tarjan(v,x);
                low[x]=min(low[x],low[v]);
                if(low[v]>=dfn[x]){
                    int w;
                    G2.adde(++tot,x);
                    do{
                        w=st[st[0]--];
                        G2.adde(tot,w);
                    }while(w!=v);
                }
            }
            else
                low[x]=min(low[x],dfn[v]);
        }
    }
    inline void dfs1(int x,int anc){
        re int v;
        sz[x]=1,son[x]=0,fa[x]=anc,
        dep[x]=dep[anc]+1,dis[x]=dis[anc]+(x<=n);
        go2(x){
            v=G2.to[e];
            if(v==anc)continue;
            dfs1(v,x);
            sz[x]+=sz[v];
            if(sz[v]>sz[son[x]])
                son[x]=v;
        }
    }
    inline void dfs2(int x,int up){
        top[x]=up,dfn[x]=++dfc;
        if(son[x])dfs2(son[x],up);
        go2(x){
            int v=G2.to[e];
            if(v==fa[x]||v==son[x])continue;
            dfs2(v,v);
        }
        low[x]=dfc;
    }
    inline bool cmp(int a,int b){
        return dfn[a]<dfn[b];
    }
    inline int lca(int u,int v){
        for(;top[u]^top[v];dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]]);
        return dep[u]<dep[v]?u:v;
    }
    inline void solve(){
        G1.clear(),G2.clear(),dfc=0,st[0]=0;
        ms(dfn,0);
        gii(n,m),tot=n;
        rep(i,1,m)gii(x,y),G1.adde(x,y);
        rep(i,1,tot)
            if(!dfn[i])
                tarjan(i,0);
        dfc=0,dfs1(1,0),dfs2(1,1);
        int q,k,l,ans;
        //rep(i,1,tot)printf("At:%d %d %d
    ",dfn[i],low[i],top[i]);
        gi(q);
        for(;q--;){
            gi(k);
            rep(i,1,k)gi(a[i]);
            sort(a+1,a+k+1,cmp);l=k;
            rep(i,1,k-1)a[++l]=lca(a[i],a[i+1]);
            sort(a+1,a+l+1,cmp);
            l=unique(a+1,a+l+1)-a-1;
            ans=a[1]<=n,st[0]=0;
            rep(i,1,l){
                for(;st[0]&&low[st[st[0]]]<dfn[a[i]];)--st[0];
                if(st[0])ans+=dis[a[i]]-dis[st[st[0]]];
                st[++st[0]]=a[i];
            }
            write(ans-k),putchar('
    ');
        }
    }
    int main(){
        gi(T);
        for(;T--;solve());
        return 0;
    }
    code
  • 相关阅读:
    [Ceoi2016|BZOJ4936] Match
    下载/拷贝下来的压缩包打开内容为空解决方案
    [POI2012]OKR-A Horrible Poem
    [SNOI2017]礼物
    LuoguP3398 仓鼠找sugar
    转:看图说话Image Caption之评价指标、NIC(Neural Image Caption)模型和attention
    转:Cascade R-CNN,一个使你的检测更加准确的网络
    图像理解之物体检测object detection,模型rcnn/fastrcnn/fasterrcnn原理及概念
    深度残差网络
    转:图像分类、物体检测、物体分割、实例分割、语义分割
  • 原文地址:https://www.cnblogs.com/Stump/p/9281524.html
Copyright © 2011-2022 走看看