zoukankan      html  css  js  c++  java
  • EOJ921 熟练剖分

    考虑到期望的线性性,将本题转化为计数问题。

    (f(x,i)) 为以 (x) 为根的子树中,轻边数量最大为 (i) 的方案数,其转移复杂度为 (O(n^3)),无法接受。于是再加一维,得 (f(x,i,0/1))(0/1) 表示是否已经选择了重边,得转移为:

    [largeegin{aligned} f(x,i,0)=&f(x,i,0)sum_{j=0}^{i-1}f(y,j,1)+f(y,i-1,1)sum_{j=0}^{i-1}f(x,j,0) \ f(x,i,1)=&f(x,i,0)sum_{j=0}^if(y,j,1)+f(x,j,1)sum_{j=0}^{i-1}f(y,k,1)+ \ &f(y,i-1,1)sum_{j=0}^{i-1}f(x,j,1)+f(y,i,1)sum_{j=0}^{i-1}f(x,j,0) end{aligned} ]

    复杂度为 (O(n^2))

    #include<bits/stdc++.h>
    #define maxn 3010
    #define p 1000000007
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,rt;
    ll ans,val=1;
    int son[maxn],siz[maxn],fa[maxn];
    ll f[maxn][maxn][2],g[maxn][2],s1[maxn][2],s2[maxn][2];
    struct edge
    {
        int to,nxt;
    }e[maxn];
    int head[maxn],edge_cnt;
    void add(int from,int to)
    {
        e[++edge_cnt]={to,head[from]},head[from]=edge_cnt;
    }
    ll inv(ll x)
    {
        ll y=p-2,v=1;
        while(y)
        {
            if(y&1) v=v*x%p;
            x=x*x%p,y>>=1;
        }
        return v;
    }
    void dfs(int x)
    {
        siz[x]=f[x][0][!son[x]]=1;
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to;
            dfs(y),siz[x]+=siz[y];
            for(int j=0;j<=siz[x];++j)
                for(int k=0;k<=1;++k)
                    s1[j][k]=f[x][j][k],s2[j][k]=f[y][j][k];
            for(int j=1;j<=siz[x];++j)
                for(int k=0;k<=1;++k)
                    s1[j][k]=(s1[j][k]+s1[j-1][k])%p,s2[j][k]=(s2[j][k]+s2[j-1][k])%p;
            for(int j=0;j<=siz[x];++j) g[j][1]=f[x][j][0]*s2[j][1]%p;
            for(int j=1;j<=siz[x];++j)
            {
                g[j][0]=(f[x][j][0]*s2[j-1][1]%p+f[y][j-1][1]*s1[j-1][0]%p)%p;
                g[j][1]=(g[j][1]+f[x][j][1]*s2[j-1][1]%p+f[y][j-1][1]*s1[j-1][1]%p+f[y][j][1]*s1[j-1][0]%p)%p;
            }
            for(int j=0;j<=siz[x];++j)
                for(int k=0;k<=1;++k)
                    f[x][j][k]=g[j][k],g[j][k]=0;
        }
    }
    int main()
    {
        read(n);
        for(int i=1;i<=n;++i)
        {
            read(son[i]);
            if(son[i]) val=val*son[i]%p;
            for(int j=1,x;j<=son[i];++j) read(x),add(i,x),fa[x]=i;
        }
        for(int i=1;i<=n;++i)
        {
            if(!fa[i])
            {
                rt=i;
                break;
            }
        }
        dfs(rt);
        for(int i=1;i<=n;++i) ans=(ans+f[rt][i][1]*i%p)%p;
        printf("%lld",ans*inv(val)%p);
        return 0;
    }
    
  • 相关阅读:
    通过docker把本地AspNetCore WebAPI镜像打包到阿里云镜像仓库并在centos部署
    记一次Java AES 加解密 对应C# AES加解密 的一波三折
    .Net Core MVC实现自己的AllowAnonymous
    Net Core 中间件实现修改Action的接收参数及返回值
    手把手教你实现自己的abp代码生成器
    C# 实现Jwtbearer Authentication
    vs2017调试浏览器闪退
    ABP 邮箱设置
    FastJson反序列化获取不到值
    内网环境下搭建maven私服小技巧
  • 原文地址:https://www.cnblogs.com/lhm-/p/13974168.html
Copyright © 2011-2022 走看看