zoukankan      html  css  js  c++  java
  • [HEOI2014]大工程

    description

    题面

    data range

    [nle 10^6, qle 5 imes 10^4,sum kle 2 imes n ]

    solution

    还是虚树的题

    这道题就相对比较容易了

    直接建出虚树,考虑每条边对答案的贡献,再在树上做一个最长链和最短链就可以了

    之前似乎一直在和空气斗智斗勇来着

    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=998244353;
    const int N=2000010;
    const dd pi=acos(-1);
    const int inf=2147483647;
    const ll INF=1e18+1;
    const ll P=100000;
    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;
    }
     
    il void file(){
        srand(time(NULL)+rand());
        freopen(FILE".in","r",stdin);
        freopen(FILE".out","w",stdout);
    }
     
    int n,q,m,k;
    int head[N],nxt[N<<1],to[N<<1],cnt;
    int dhead[N],dnxt[N<<1],dto[N<<1],dcnt;
    il void addedge(int u,int v){
        dto[++dcnt]=v;
        dnxt[dcnt]=dhead[u];
        dhead[u]=dcnt;
    }
     
    int fa[N],sz[N],dep[N],son[N],top[N],dfn[N],low[N],tot;
    void dfs1(int u,int ff){
        fa[u]=ff;dep[u]=dep[ff]+1;sz[u]=1;
        for(RG int i=head[u];i;i=nxt[i]){
            RG int v=to[i];if(v==ff)continue;
            dfs1(v,u);sz[u]+=sz[v];
            if(sz[son[u]]<sz[v])son[u]=v;
        }   
    }
    void dfs2(int u,int tp){
        top[u]=tp;dfn[u]=++tot;
        if(son[u])dfs2(son[u],tp);
        for(RG int i=head[u];i;i=nxt[i]){
            RG int v=to[i];if(v==fa[u]||v==son[u])continue;
            dfs2(v,v);
        }
        low[u]=++tot;
    }
    il int lca(int u,int v){
        while(top[u]!=top[v]){
            if(dep[top[u]]<dep[top[v]])swap(u,v);
            u=fa[top[u]];
        }
        return dep[u]<dep[v]?u:v;
    }
     
    bool cmp_dfn(int i,int j){return dfn[i]<dfn[j];}
    int s[N],cal[N],tp,mark[N],siz[N];
    ll f[N],g[N],sum,maxn,minn;
    void solve(int u){
        siz[u]=mark[u];
        for(RG int i=dhead[u];i;i=dnxt[i]){
            RG int v=dto[i];solve(v);siz[u]+=siz[v];
        }
        for(RG int i=dhead[u];i;i=dnxt[i]){
            RG int v=dto[i],d=dep[v]-dep[u];
            sum+=1ll*d*siz[v]*(m-siz[v]);
            maxn=max(maxn,f[u]+f[v]+d);
            minn=min(minn,g[u]+g[v]+d);
            f[u]=max(f[u],f[v]+d);
            g[u]=min(g[u],g[v]+d);
        }
        if(mark[u]){maxn=max(maxn,f[u]);if(g[u])minn=min(minn,g[u]);}
        if(mark[u])g[u]=0,f[u]=max(f[u],0ll);
    }
     
    int main()
    {
        n=read();
        for(RG int i=1,u,v;i<n;i++){
            u=read();v=read();
            to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
            to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;       
        }
        dfs1(1,0);dfs2(1,1);
        for(RG int i=1;i<=n;i++)f[i]=-INF,g[i]=INF;
         
        q=read();
        for(RG int i=1;i<=q;i++){
            m=read();k=tp=dcnt=0;
            for(RG int j=1;j<=m;j++)s[++k]=read(),mark[s[k]]=1;
            sort(s+1,s+k+1,cmp_dfn);
            for(RG int j=1;j<m;j++)s[++k]=lca(s[j],s[j+1]);s[++k]=1;
            sort(s+1,s+k+1,cmp_dfn);k=unique(s+1,s+k+1)-s-1;
            for(RG int j=1;j<=k;j++){
                while(tp&&low[cal[tp]]<dfn[s[j]])tp--;
                if(tp)addedge(cal[tp],s[j]);cal[++tp]=s[j];
            }
            sum=0;maxn=0;minn=INF;solve(1);
            printf("%lld %lld %lld
    ",sum,minn,maxn);
            for(RG int j=1;j<=k;j++)
                dhead[s[j]]=mark[s[j]]=0,f[s[j]]=-INF,g[s[j]]=INF;
        }
        return 0;
    }
    
  • 相关阅读:
    python自动化测试应用-番外篇--接口测试2
    python自动化测试应用-番外篇--接口测试1
    篇3 安卓app自动化测试-搞定界面元素
    selenium操作拖拽实现无效果的替代方案
    python自动化测试应用-第7篇(WEB测试)--Selenium进阶篇
    python自动化测试应用-第6篇(WEB测试)--Selenium元素篇
    篇4 安卓app自动化测试-Appium API进阶
    进程和应用程序生命周期
    任务和返回栈
    activity状态变化
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9494157.html
Copyright © 2011-2022 走看看