zoukankan      html  css  js  c++  java
  • bzoj 3872: [Poi2014]Ant colony【树形dp+二分】

    啊我把分子分母混了WA了好几次……
    就是从食蚁兽在的边段成两棵树,然后dp下去可取的蚂蚁数量区间,也就是每次转移是l[e[i].to]=l[u](d[u]-1),r[e[i].to]=(r[u]+1)(d[u]-1)-1,这里注意当l>maxm的时候就return,不然之后的没有贡献而且会爆long long
    然后把每个dp到的叶子都二分一下看他的贡献区间里有几群蚂蚁加进答案里最后乘上k即可

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=1000005;
    long long n,m,k,h[N],cnt,rt1,rt2,a[N],d[N],l[N],r[N],ans;
    struct qwe
    {
        long long ne,to;
    }e[N<<1];
    long long read()
    {
        long long r=0,f=1;
        char p=getchar();
        while(p>'9'||p<'0')
        {
            if(p=='-')
                f=-1;
            p=getchar();
        }
        while(p>='0'&&p<='9')
        {
            r=r*10+p-48;
            p=getchar();
        }
        return r*f;
    }
    void add(long long u,long long v)
    {
        cnt++;
        d[u]++;
        e[cnt].ne=h[u];
        e[cnt].to=v;
        h[u]=cnt;
    }
    long long ef(long long w)
    {
        long long l=1,r=m,ans=0;
        while(l<=r)
        {
            long long mid=(l+r)>>1;
            if(a[mid]<=w)
                l=mid+1,ans=mid;
            else
                r=mid-1;
        }
        return ans;
    }
    void dfs(long long u,long long fa,long long ll,long long rr)
    {
    	if(ll>a[m])
    		return;
        l[u]=ll,r[u]=rr;
    	if(d[u]==1)
    		ans+=ef(r[u])-ef(l[u]-1);
        for(long long i=h[u];i;i=e[i].ne)
            if(e[i].to!=fa)
                dfs(e[i].to,u,ll*(d[u]-1),(rr+1)*(d[u]-1)-1);
    }
    int main()
    {
        n=read(),m=read(),k=read();
        for(long long i=1;i<=m;i++)
            a[i]=read();
        sort(a+1,a+1+m);
        rt1=read(),rt2=read();
        for(long long i=1;i<n-1;i++)
        {
            long long x=read(),y=read();
            add(x,y),add(y,x);
        }
    	d[rt1]++,d[rt2]++;
        dfs(rt1,0,k,k);
        dfs(rt2,0,k,k);
        // for(long long i=1;i<=n;i++)
            // cerr<<l[i]<<" "<<r[i]<<endl;
        printf("%lld
    ",ans*k);
        return 0;
    }
    
  • 相关阅读:
    HTML、CSS、JS 复习——序
    HTML + CSS短标题(二,三,四文字长度)两端对齐的方式
    Supper关键字
    java的重写
    java重载
    Java继承
    JAVA访问权限控制
    (转)java类初始化顺序
    Java 数组和集合
    Java 方法签名
  • 原文地址:https://www.cnblogs.com/lokiii/p/9787270.html
Copyright © 2011-2022 走看看