• AT5202 [AGC038E] Gachapon


    题目链接

    被二月份的自己爆踩了

    弱化版:喂鸽子

    显然可以用 min-max 定理来搞:

    [Sigma S = sum_{i in S}a_i ]

    [egin{aligned} E(max_{i in S}(x_i))\ &=sum_{T in S,T ot= phi}(-1)^{|T|+1}E(min_{i in T}(x_i))\ &=sum_{T in S,T ot= phi}(-1)^{|T|+1}frac{Sigma S}{Sigma T}E'(min_{i in T}(x_i))\ &= sum_{T in S,T ot= phi}(-1)^{|T| + 1}frac{Sigma S}{Sigma T}sum_{t}P(x=t)t\ &= sum_{T in S,T ot= phi}(-1)^{|T| + 1}frac{Sigma S}{Sigma T}sum_{tge 0} P(x > t)\ &= sum_{T in S,T ot= phi}(-1)^{|T|+1}frac{Sigma S}{Sigma T}sum_{j ge 0}[frac{x^j}{j!}]prod_{i in T}sum_{d < b_i}(frac{a_i}{Sigma T})^d frac{x^d}{d!}\ &= sum_{T in S,T ot= phi}(-1)^{|T|+1}frac{Sigma S}{Sigma T}sum_{j = 0}^B (1/ Sigma T)^j[frac{(frac{x}{Sigma T})^j}{j!}]prod_{i in T}sum_{d < b_i}a_i^d frac{(frac{x}{Sigma T})^d}{d!}\ &= Sigma Ssum_{T in S,T ot= phi}sum_{j = 0}^B (frac{1}{Sigma T})^{j+1}(-1)^{|T|+1}[frac{x^j}{j!}]prod_{i in T}sum_{d < b_i}a_i^d frac{x^d}{d!}\ end{aligned}]

    发现好多地方都与 (Sigma T) 有关,可以尝试用 (Sigma T) 做状态的一部分来背包DP以防止枚举子集。但是只有 (Sigma T) 还不够,我们还需要知道当前 (|T|) 的奇偶性和 (j)(选的总次数,即背包体积)。可以直接把 ((-1)^{|T|+1}) 乘进去。

    (f[i][s][j]) 表示考虑了前 (i) 个,选择的集合中 (Sigma T)(s),的背包数组(含若干 ((-1)) 的贡献)。讨论第 (i) 个是否加入 (T) 集合以及加进去多少:

    [egin{aligned} f(i,s,j) &gets f(i-1,s,j)\ &gets f(i-1,s-a_i,j-k) imes (-1) imes a_i^k imes frac{1}{k!},k < b_i end{aligned}]

    注意这个 (f(i,s,j)) 最后要乘 (j!)。转移要除阶乘,最后要乘阶乘,就又是用多项式乘法来算 EGF 的那些套路了。

    总结一下涉及的套路:

    • min-max 容斥

    • (sum_{i} P(x=i) imes i = sum_{i ge 0}P(x>i))

    • 指数生成函数 与 背包DP

    • 状态中记录关键信息以避免枚举子集

    ll f[N][N];
    inline void work() {
    	f[0][0] = -1;
    	int sm = 0;
    	for (int i = 1; i <= n; ++i) {
    		sm += a[i];
    		for (int s = A; ~s; --s) {
    			for (int j = 0; j <= B; ++j) {
    				if (s - a[i] < 0) continue;
    				ll lstf = f[s][j]; f[s][j] = 0;
    				ll tmp = 1;
    				for (int k = 0; k < b[i] && k <= j; ++k, tmp = tmp * a[i] % P) {
    					f[s][j] = (f[s][j] + f[s - a[i]][j - k] * tmp % P * jieni[k]) % P;
    				}
    				f[s][j] = (lstf - f[s][j] + P) % P;
    			}
    		}
    	}
    	ll ans = 0;
    	for (int s = 0; s <= A; ++s) {
    		ll sn = quickpow(s, P - 2);
    		ll tmp = sn;
    		for (int j = 0; j < B; ++j, tmp = tmp * sn % P) {
    			ans = (ans + tmp * f[s][j] % P * jie[j]) % P;
    		}
    	}
    	ans = ans * A % P;
    	printf("%lld
    ", (ans % P + P) % P);
    }
    
  • 相关阅读:
    遗产继承骗局
    Nginx配置https和wss
    Servlet乱码问题
    logback+slf4j作为日志系统
    InteliJ Idea通过maven创建webapp
    pip安装注意事项
    [转]TCP(HTTP)长连接和短连接区别和怎样维护长连接
    Python Socket编程初探
    有用的git片段
    Python使用chardet包自动检测编码
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13690981.html
Copyright © 2020-2023  润新知