Wannafly挑战赛25 C 期望操作数 数学

题目

题意:给你你一个数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\n",f[r-l]); 
22     } 
23 }

 

 

        

posted @ 2018-10-01 00:15  口香糖万岁  阅读(203)  评论(0编辑  收藏  举报