【HDU2019多校】1005 - Everything Is Generated In Equal Probability(期望可加性)

题目:
给出一个数n,在【1,n】等概率的选择一个数i,在【1,i】内每次等概率的选择一个数字组成长度为i的序列,这个序列中所有数都在【1,i】内,且两两互不相同(也就是说这个长度为i的序列是1->n的一种排列),以这个长度为i的序列为参数array运行程序:

1.统计array中的逆序对数目

2.统计array的子序列的逆序对数目(子序列的长度为0->length(array)),

3.array长度为0结束程序,否则以这个子序列为参数array运行程序,重复1,2

求最终逆序对数目的期望值,对998244353取模

程序如下:

input:

0

1

2

output:

0

332748118

554580197

SOLUTION:

对于这种无限向里递归,我们可以套路的使用递推来推出来

 CODE:

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long ll;
const int maxn = 3005;
const int mod  = 998244353;
ll mu[maxn], zi[maxn], f[maxn], c[maxn][maxn];
ll qkpow(ll a,ll p,ll mod)
{
    ll t=1,tt=a%mod;
    while(p)
    {
        if(p&1)t=t*tt%mod;
        tt=tt*tt%mod;
        p>>=1;
    }
    return t;
}
ll getInv(ll a,ll mod)
{
    return qkpow(a,mod-2,mod);
}
void init()
{
    //组合数
    for(int i = 1; i < maxn;i++)
    {
        c[i][i] = 1, c[i][0] =1;
        for(int j = 1; j < i; j++)
            c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
    }
    //分母
    mu[1] = 2;
    for(int i = 2; i < maxn; i++)
        mu[i] = (mu[i - 1]  * 2) % mod;

    f[0] = 0, f[1] = 0;
    for(int i = 2; i < maxn; i++)
    {
        //或者不用单开一个分子数组,存到f[i]里
        zi[i] = (c[i][2] * mu[i-1]) % mod;//原序列的逆序对期望值!!不要写成c[i][2]/2 * mu[i-1] 因为c[2][2]/2=0,而应该是0.5
        zi[i]=0;
        for(ll j = 0; j < i; j++)
            zi[i] = (zi[i] + (c[i][j] * f[j]) % mod) % mod;
        f[i] = (zi[i] * getInv(mu[i] -1 , mod)) % mod;//得到第二个式子的f[i]
        f[i] += (1ll*c[i][2] * mu[i-1]%mod*getInv(mu[i]-1,mod)) % mod;
        f[i] %=mod;
        //p rintf("f[%d]: %lld\n", i, f[i]);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int x;
    init();
    while(cin >> x)
    {
        int ans = 0;
        for(int i = 1; i <= x; i++)
            ans = (ans + f[i]) % mod;
        ans = (ans * getInv(x, mod) ) % mod;
        cout << ans << endl;
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/zhangbuang/p/11285577.html
今日推荐