AT4119 [ARC096C] Everything on It
作者:互联网
https://www.luogu.com.cn/problem/AT4119
你说原来那个题面蛮好的你换了它干什么你告诉我
截一张qiuly神仙的翻译
换汤不换药啊
设\(f[i]\)表示钦定\(i\)种酱不合法的方案数,直接拿\(ANS=\sum\limits_{i=0}^n \binom{n}{i} (-1)^i f(i) \times 2^{2^{n-i}}\)
因为包含不合法酱的集合下面已经处理了,所以直接把剩下的随便选即可
考虑怎么求\(f(i)\)
设\(g(i,j)\)表示把\(i\)种酱放在\(j\)个碗里且不合法的方案数
可以得到一个显然的转移方程
\[g(i,j)=g(i-1,j-1)+g(i-1,j)\times(j+1) \]加一是因为还可以不放
然后显然
\[f(i)=\sum_{j=0}^i g(i,j) \times(2^{(n-i)})^j \]把没钦定的酱也可以加进这\(j\)个碗中,所以\(j\)次方
一步步推,不要急着跳步
code:
#include<bits/stdc++.h>
#define ll long long
#define N 3005
using namespace std;
ll g[N][N], c[N][N];
int n, mod;
ll qpow(ll x, ll y, ll mod) { y %= mod - 1;
ll ret = 1;
for(; y; y >>= 1, x = x * x % mod) if(y & 1) ret = ret * x % mod;
return ret;
}
int main() {
scanf("%d%d", &n, &mod);
for(int i = 0; i <= n; i ++) c[i][0] = g[i][0] = 1;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= i; j ++)
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod,
g[i][j] = (g[i - 1][j - 1] + 1ll * (j + 1) * g[i - 1][j] % mod) % mod;
// for(int i = 1; i <= n; i ++) {
// for(int j = 0; j <= n; j ++) printf("%lld ", g[i][j]); printf("\n");
// }
ll ans = 0;
for(int i = 0; i <= n; i ++) {
ll ret = 0;
for(int j = 0; j <= i; j ++) (ret += g[i][j] * qpow(2, 1ll * (n - i) * j, mod) % mod) %= mod;
ret = ret * c[n][i] % mod * qpow(2, qpow(2, n - i, mod - 1), mod) % mod;
// printf("%lld ", ret);
if(i & 1) ans = (ans - ret + mod) % mod;
else ans = (ans + ret) % mod;
}
printf("%lld", ans);
return 0;
}
标签:int,ll,ret,times,Everything,ARC096C,long,AT4119,mod 来源: https://www.cnblogs.com/lahlah/p/15937978.html