题目

题意:给你你一个数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的时候与不同,反正被秀到

 #include<bits/stdc++.h>
#define mod 998244353ll
#define ll long long
#define N 10000010
using namespace std;
int T,l,r;
ll t,f[N],inv[N];
int main()
{
scanf("%d",&T);
inv[]=;
for (int i=;i<N;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
for (int i=;i<N;i++)
{
f[i]=(t*inv[i]+(i+)*inv[i])%mod;
t=(t+f[i])%mod;
}
while (T--)
{
scanf("%d%d",&l,&r);
printf("%lld\n",f[r-l]);
}
}

    

05-23 11:36