CF995F Cowmpany Cowmpensation 动态规划+容斥原理

数数题还是要多练啊

code:

#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#define N 3004
#define ll long long
#define mod 1000000007
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,D,g[N],f[N][N],s[N][N],fac[N],inv[N];
vector<int>G[N];
int qpow(int x,int y)
{
    int tmp=1;
    for(;y;y>>=1,x=(ll)x*x%mod)
        if(y&1) tmp=(ll)tmp*x%mod;
    return tmp;
}
int C(int x,int y) { return (ll)fac[x]*inv[y]%mod*inv[x-y]%mod; }
void dfs(int x)
{
    for(int i=1;i<=n;++i) f[x][i]=1;
    for(int i=0;i<G[x].size();++i)
    {
        int y=G[x][i];
        dfs(y);
        for(int j=1;j<=n;++j) f[x][j]=1ll*f[x][j]*s[y][j]%mod;
    }
    for(int i=1;i<=n;++i) s[x][i]=(ll)(s[x][i-1]+f[x][i])%mod;
}
int main()
{
    // setIO("input");
    int i,j;
    scanf("%d%d",&n,&D);
    for(i=2;i<=n;++i)
    {
        int ff;
        scanf("%d",&ff),G[ff].push_back(i);
    }
    dfs(1);
    fac[0]=inv[0]=1;
    for(i=1;i<=n;++i) fac[i]=(ll)i*fac[i-1]%mod, inv[i]=qpow(fac[i],mod-2);
    for(i=1;i<=n;++i)
    {
        g[i]=f[1][i];
        for(j=1;j<i;++j)
            g[i]=(ll)(g[i]-(ll)C(i-1,i-j)*g[j]%mod+mod)%mod;
    }
    int ans=0;
    int tmp=1;
    for(i=1;i<=min(D,n);++i)
    {
        tmp=(ll)tmp*qpow(i,mod-2)%mod*(D-i+1)%mod;
        ans=(ll)(ans+(ll)tmp*g[i]%mod)%mod;
    }
    printf("%d\n",ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/guangheli/p/12174561.html

时间: 2024-10-30 04:05:11

CF995F Cowmpany Cowmpensation 动态规划+容斥原理的相关文章

CF995F Cowmpany Cowmpensation

题目链接:http://codeforces.com/contest/995/problem/F 题目大意: 给定一棵 \(n\) 个节点的有根树(根为 \(1\) 号结点),为这棵树上的每一个结点赋值(赋值的范围为 \([1,D]\)),要求父结点的值不小于子结点值,问有多少种赋值方案. \(1 \le n \le 3000, 1 \le D \le 10^9\) 知识点: 树形DP.拉格朗日插值法 解题思路: 可以证明:对于一棵有 \(n\) 个结点的树,其答案是一个关于 \(D\) 的 \

[CF995F]Cowmpany Cowmpensation[树形dp+拉格朗日插值]

题意 给你一棵树,你要用不超过 \(D\) 的权值给每个节点赋值,保证一个点的权值不小于其子节点,问有多少种合法的方案. \(n\leq 3000, D\leq 10^9\) 分析 如果 \(D\) 比较小的话可以考虑状态 \(f_{i,j}\) 表示点 \(i\) 的权值是 \(j\) 的方案总数,\(g_{i,j}\) 表示 \(\sum_\limits{k=1}^jf_{i,j}\) ,转移也比较显然:\(f_{i,j}=\prod g_{son,j}\) 先证明结论:前?\(n\)?个正

洛谷P1450 [HAOI2008]硬币购物 动态规划 + 容斥原理

洛谷P1450 [HAOI2008]硬币购物 动态规划 + 容斥原理 1.首先我们去掉限制 假设 能够取 无数次 也就是说一开始把他当做完全背包来考虑 离线DP 预处理 复杂度 4*v 用f[ i ] 表示 空间 为 i 的方案数 答案ans 其实就是所有方案 - 所有超过限制的方案 限制指的就是题目中限制 某个硬币有几枚 然后所有超过限制的方案用容斥来做 所有超过限制的方案 要减 == -1 超过限制的方案 - 2 超过限制的方案 - 3 超过限制的方案 - 4 超过限制的方案 + 1和2 超

【BZOJ3622】已经没有什么好害怕的了 动态规划+容斥原理

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44836095"); } 题解: 首先我们给A数组(糖果)和B数组(药片)从小到大排个序. lasti 表示一个极大值 x 使得 Bx<Ai . f(i,j) 表示枚举到第 Ai 时,有至少 j 对匹配,使得 A???>B

Codeforces 995F Cowmpany Cowmpensation - 组合数学

题目传送门 传送点I 传送点II 传送点III 题目大意 给定一个棵$n$个点的有根树和整数$D$,给这$n$个点标号,要求每个节点的标号是正整数,且不超过父节点的标号,根节点的标号不得超过D. 很容易地能得到$O(nD)$的动态规划:设$f[i][j]$表示$i$号点标为$j$在它的子树内的方案数. 写写它的转移方程:$f[i][j] = \prod_{s \in Son(i)}\sum_{k = 1}^{j} f[s][k]$. 设$g[i][j]=\sum_{k = 1}^{j}f[i][

bzoj 4767 两双手 - 动态规划 - 容斥原理

题目传送门 传送门I 传送门II 题目大意 一个无限大的棋盘上有一只马,设马在某个时刻的位置为$(x, y)$, 每次移动可以将马移动到$(x + A_x, y + A_y)$或者$(x + B_x, y + B_y)$.棋盘上有$n$个禁止位置不能经过,问马从$(0, 0)$走到$(E_x, E_y)$的方案数. 容斥是显然的. 每确定经过$k$个禁止位置的方案数的容斥系数是$(-1)^{k}$. 考虑带上容斥系数来动态规划, 注意到去掉重复的禁止位置后,$(0, 0), (E_x, E_y)

BZOJ 2024 SHOI2009 舞会 动态规划+容斥原理+高精度

题目大意:给定两个序列,求有多少个匹配满足a[i]<b[i]的对数不超过k对 见http://blog.csdn.net/popoqqq/article/details/44514113 高精度已废... #include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define M 202 using na

BZOJ 3622 已经没有什么好害怕的了 动态规划+容斥原理

题目大意:给定两个长度为n个序列,保证这2n个数字两两不同,求有多少匹配满足a[i]>b[i]的数对数比a[i]<b[i]的数对数多k もう何も怖くない 题解:http://www.cnblogs.com/dyllalala/p/3900077.html OTZ 神思路根本就是想不到啊QAQ でも...もう何も怖くない...(大雾 此外我们可以引入一下WTY公式: C[i][j]=C[i-1][j]*C[i-1][j-1] ...脑残怎么治啊... #include <cstdio>

51Nod1634 刚体图 动态规划 容斥原理 排列组合

原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1634.html 题目传送门 - 51Nod1634 题意 基准时间限制:1 秒 空间限制:131072 KB 分值: 640 难度:8级算法题 计算机科学中,图可以看做是点集和边集所组成的二元组. 通过给每个点设置一个平面坐标,图可以镶嵌在欧几里得平面中. 一个图被认为是刚体,如果该图无法只改变其中一部分的形状,而使得余下的部分的形状保持不变. 例如上图中的 (a) (b) (c) 都是刚体. 为