题解 P9142 【[THUPC 2023 初赛] 欺诈游戏】
设走私者放
- 走私者放
i 元时,走私者的期望收益为E_1(i) = i \displaystyle\sum_{j = 0}^{i - 1} g(j) + \frac{1}{2} \sum_{j = i + 1}^n j g(j) 。 - 检察官猜
i 元时,走私者的期望收益为E_2(i) = \frac{i}{2} \displaystyle\sum_{j = 0}^{i - 1} f(j) + \sum_{j = i + 1}^n j f(j) 。
这里我们以第一个式子为例(第二个式子的后续推导与之相似)。
下面是一个小但我之前不会的套路。
注意到“你需要保证,在一方的策略不变的情况下,另一方无论如何改变自己的策略,都不能使自己的期望收益比原来多。”,考虑调整法,设
然后有
考虑抓出比较像的相邻两项来讨论,下面假定我们讨论
进行化简后可得:
于是我们可以将所有
同理可得:
线性求逆即可。时间复杂度为
代码:
#include <stdio.h>
typedef long long ll;
const int mod = 998244353;
ll inv[800007], f[400007], g[400007];
inline void init(int n){
inv[0] = inv[1] = 1;
for (register int i = 2; i <= n; i++){
inv[i] = mod - (mod / i) * inv[mod % i] % mod;
}
}
inline ll quick_pow(ll x, ll p, ll mod){
ll ans = 1;
while (p){
if (p & 1) ans = ans * x % mod;
x = x * x % mod;
p >>= 1;
}
return ans;
}
int main(){
int n;
ll pre = 0, sumf = 0, sumg = 0;
scanf("%d", &n);
init(n * 2);
f[0] = 1;
for (register int i = 1; i <= n; i++){
pre = (pre + f[i - 1]) % mod;
f[i] = (f[i - 1] * (i - 1) % mod + pre) % mod * inv[i * 2] % mod;
}
for (register int i = 0; i <= n; i++){
sumf = (sumf + f[i]) % mod;
}
sumf = quick_pow(sumf, mod - 2, mod);
for (register int i = 0; i <= n; i++){
printf("%lld ", f[i] * sumf % mod);
}
printf("\n");
pre = 0;
g[0] = 1;
for (register int i = 1; i <= n; i++){
pre = (pre + g[i - 1]) % mod;
g[i] = (g[i - 1] * (i - 1) % mod + pre) % mod * 2 % mod * inv[i] % mod;
}
for (register int i = 0; i <= n; i++){
sumg = (sumg + g[i]) % mod;
}
sumg = quick_pow(sumg, mod - 2, mod);
for (register int i = 0; i <= n; i++){
printf("%lld ", g[i] * sumg % mod);
}
return 0;
}