bzoj2655 calc [拉格朗日插值]
2018-03-27 22:26
204 查看
Description:
一个序列a1,...,ana1,...,an是合法的,当且仅当:
长度为给定的nn。
a1,...,ana1,...,an都是[1,A][1,A]中的整数。
a1,...,ana1,...,an互不相等。
一个序列的值定义为它里面所有数的乘积,即a1a2...ana1a2...an。
求所有不同合法序列的值的和。
两个序列不同当且仅当他们任意一位不一样。
输出答案对一个数modmod取余的结果。
Solution:
考虑一个暴力的dp,dp[i][j]dp,dp[i][j]表示前ii个数选jj个数。
那么转移即为dp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗i∗jdp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗i∗j 表示选或不选,并且枚举插入的位置。
由于这个dpdp式是一个2∗n2∗n的多项式,所以我们插值求第AA项即可。
注意插值如果从11开始要插到2∗n+12∗n+1次。
一个序列a1,...,ana1,...,an是合法的,当且仅当:
长度为给定的nn。
a1,...,ana1,...,an都是[1,A][1,A]中的整数。
a1,...,ana1,...,an互不相等。
一个序列的值定义为它里面所有数的乘积,即a1a2...ana1a2...an。
求所有不同合法序列的值的和。
两个序列不同当且仅当他们任意一位不一样。
输出答案对一个数modmod取余的结果。
Solution:
考虑一个暴力的dp,dp[i][j]dp,dp[i][j]表示前ii个数选jj个数。
那么转移即为dp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗i∗jdp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗i∗j 表示选或不选,并且枚举插入的位置。
由于这个dpdp式是一个2∗n2∗n的多项式,所以我们插值求第AA项即可。
注意插值如果从11开始要插到2∗n+12∗n+1次。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1005; int n, A, P; ll pre[maxn], suf[maxn], inv[maxn], dp[maxn][maxn]; ll calc(ll *f, ll u, int n) { pre[0] = 1; suf[n + 2] = 1; for(int i = 1; i <= n + 1; ++i) { pre[i] = pre[i - 1] * (u - i + P) % P; } for(int i = n + 1; i; --i) { suf[i] = suf[i + 1] * (u - i + P) % P; } ll ret = 0, tmp; for(int i = 1; i <= n + 1; ++i) { tmp = f[i] * pre[i - 1] % P * suf[i + 1] % P * inv[i - 1] % P * inv[n - i + 1] % P; if((n - i + 1) & 1) { tmp = P - tmp; } ret = (ret + tmp) % P; } return ret; } int main() { scanf("%d%d%d", &A, &n, &P); inv[0] = inv[1] = 1; for(int i = 2; i < maxn; ++i) { inv[i] = (P - P / i) * inv[P % i] % P; } for(int i = 2; i < maxn; ++i) { inv[i] = inv[i] * inv[i - 1] % P; } dp[0][0] = 1; for(int j = 1; j <= 2 * n + 1; ++j) { for(int i = 0; i <= n; ++i) { dp[i][j] = (dp[i][j] + dp[i][j - 1]) % P; if(i) { dp[i][j] = (dp[i][j] + dp[i - 1][j - 1] * i % P * j % P) % P; } } } if(A <= 2 * n) { printf("%lld\n", dp [A]); } else { printf("%lld\n", calc(dp , A, 2 * n)); } return 0; }
相关文章推荐
- 【BZOJ】2655: calc 动态规划+拉格朗日插值
- bzoj千题计划269:bzoj2655: calc (拉格朗日插值)
- [BZOJ2655] calc - 拉格朗日插值,dp
- [BZOJ 2655]calc
- calc BZOJ 2655
- bzoj 2655: calc
- BZOJ 2655: calc
- BZOJ 2655 calc
- bzoj 2655: calc
- Bzoj2655 calc
- [BZOJ2655]calc(拉格朗日插值法+DP)
- bzoj[2655] calc
- bzoj 2655: calc [容斥原理 伯努利数]
- 【BZOJ2655】calc,dp+拉格朗日插值法
- [bzoj2655] calc
- 【XSY2536】【BZOJ2655】calc DP 数学 拉格朗日插值
- BZOJ2506: calc
- BZOJ2671 : Calc
- BZOJ 2671 Calc 数论
- bzoj 2506 calc 题解