题解 P8967 【追寻 | Pursuit of Dream】
题解
考虑设
从一个点出发,走过了若干步后,总是会到达以下两个情况之一:
- 失足从
k 个起点中的某一个从头来过; - 顺利到达终点。
前者很不容易计算,因此考虑先算出第二种情况的概率,再回来算出第一种情况。
从
- 在前进的时候不慎从头开始了;
- 某一维的值超过了对应的
d_i ,此时不可能顺利到达终点,只有可能从某个地方从头来过。
前者需要保证在
特别地,若存在
对于
似乎
容易得到
现在继续计算
到这一步,发现很难表示出从起点出发一直到失足前到底走了多少步。考虑使用容斥,假设压根没有终点只是到处乱走,那么在失足前的期望步数显然就是
整理一下
现在考虑解出
将含有
其中
参考代码
#include<bits/stdc++.h>
#define up(l, r, i) for(int i = l, END##i = r;i <= END##i;++ i)
#define dn(r, l, i) for(int i = r, END##i = l;i >= END##i;-- i)
using namespace std;
typedef long long i64;
const int INF = 2147483647;
const int MOD = 998244353;
int qread(){
int w=1,c,ret;
while((c = getchar()) > '9' || c < '0') w = (c == '-' ? -1 : 1); ret = c - '0';
while((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + c - '0';
return ret * w;
}
int qpower(int x, int y){
int r = 1;
while(y){
if(y & 1) r = 1ll * r * x % MOD;
x = 1ll * x * x % MOD, y >>= 1;
}
return r;
}
const int MAXT = 1e7 + 3;
const int MAXN = 1e2 + 3;
const int MAXK = 1e4 + 3;
int o = 1e7, n, k, p, g;
int D[MAXN], S[MAXK], Q[MAXK], P[MAXK], F[MAXK];
int M[MAXT], N[MAXT], X[MAXT], Y[MAXT], A[MAXK][MAXN];
int main(){
n = qread(), k = qread();
M[0] = 1, N[0] = 1, X[0] = 1;
up(1, o, i) M[i] = 1ll * M[i - 1] * i % MOD;
up(1, o, i) X[i] = 1ll * X[i - 1] * M[i] % MOD;
Y[o] = qpower(X[o], MOD - 2);
dn(o, 1, i) Y[i - 1] = 1ll * Y[i] * M[i ] % MOD;
up(1, o, i) N[i] = 1ll * Y[i] * X[i - 1] % MOD;
up(1, n, i) D[i] = qread();
up(1, k, i){
up(1, n, j) A[i][j] = qread(); P[i] = qread();
P[i] = 1ll * P[i] * qpower(1e8, MOD - 2) % MOD;
p = (p + P[i]) % MOD;
}
up(0, k, i){
bool f = 0;
up(1, n, j) if(D[j] < A[i][j]) f = true;
up(1, n, j) S[i] += D[j] - A[i][j];
if(f == true) Q[i] = 0; else {
Q[i] = 1ll * M[S[i]]
* qpower(qpower(n, S[i]), MOD - 2) % MOD
* qpower(1 - p + MOD, S[i]) % MOD;
up(1, n, j) Q[i] = 1ll * Q[i] * N[D[j] - A[i][j]] % MOD;
}
}
int u = 0, v = 1, np = qpower(p, MOD - 2);
up(1, k, i)
u = (u + 1ll * P[i] * np % MOD * (np - 1ll * Q[i] * qpower(p, MOD - 2) % MOD + MOD) % MOD) % MOD;
up(1, k, i)
v = (v + 1ll * P[i] * np % MOD * (Q[i] - 1 + MOD) % MOD) % MOD;
g = 1ll * u * qpower(v, MOD - 2) % MOD;
up(0, k, i)
F[i] = (1ll * (1 - Q[i] + MOD) * g % MOD + np - 1ll * Q[i] * qpower(p, MOD - 2) % MOD + MOD) % MOD;
printf("%d\n", F[0]);
return 0;
}