题意:给你你一个数x和一个数q,x<=q,每一次可以等概率把x变成[x,q]中任意一个数,问变成q的步数的期望,输出对998244353取模,多组询问
题解:首先肯定的是,可以预处理,因为只和x,q的差值有关
为了方便理解,我们先定义f[p]表示数p到q的期望,例如对于q=10,f[9]就表示x=9时,期望步数
那么就有 f[1] = 1/q * f[1]+1/q* f[2] +……+ 1/q * f[q-1] + 1
f[2] = 1/(q-1) * f[2] + ……+1/(q-1) * f[q-1]+1
……
f[q-1]=1/2 * f[q-1]+1 (例如样例7-8期望步数2)
所以就有
(q-1)/q * f[1] = 1/q * (f[2]+f[3]+……+f[q-1]+q) (q-1) * f[1] = (f[2]+f[3]+……+f[q-1]+q)
(q-2)/(q-1) * f[2] = 1/(q-1) * (f[3]+f[4]+f[q-1]+q-1) (q-2) * f[2] = (f[3]+f[4]+f[q-1]+q-1)
……
1/2* f[q-1] =1/2 * 2
因为多组询问,所以把这个数组倒着处理要方便一点
看了很多人代码,发现具体转移还可以很多种表示,可能是定义f的时候与不同,反正被秀到
1 #include<bits/stdc++.h> 2 #define mod 998244353ll 3 #define ll long long 4 #define N 10000010 5 using namespace std; 6 int T,l,r; 7 ll t,f[N],inv[N]; 8 int main() 9 { 10 scanf("%d",&T); 11 inv[1]=1; 12 for (int i=2;i<N;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod; 13 for (int i=1;i<N;i++) 14 { 15 f[i]=(t*inv[i]+(i+1)*inv[i])%mod; 16 t=(t+f[i])%mod; 17 } 18 while (T--) 19 { 20 scanf("%d%d",&l,&r); 21 printf("%lld ",f[r-l]); 22 } 23 }