2019 杭电多校 E - Everything Is Generated In Equal Probability HDU 6595 数学

给了你一个程序

程序 S1 将传入的 数组 返回一个随机子序列(不一定连续)
程序 S2 算这个数组 逆序对数量
程序 S3 算这个数组 经过S1 之后 用S2算逆序对数量

到这里 我们知道了 这个程序是在算 一个序列 包括它子序列 随机排列 最后 逆序对期望值

首先 我们知道 一个长度为n的 它随机排列的逆序对期望 C(n, 2) 可以产生多少逆序对 每个 逆序对的存在概率是/2
所以 是C(n, 2)/ 2
知道这个后面 我们就好算 算 它子序列的逆序对期望了
移向之后 我们就算出 i 子序列的个数了 在 + 上 它自身期望
答案 问的是 n 之内 的 期望 所以 我们 sum (f 1 ~ n) / n 就是答案
n^2 打表处理

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3005;
const int mod = 998244353;
int n;
int c[maxn][maxn], mi[maxn];
int f[maxn], ans[maxn];

int q_mod(int a, int b) {
    int res = 1;
    for(; b; b >>= 1) {
        if(b & 1) res = 1ll * res * a % mod;
        a = 1ll * a * a % mod;
    }
    return res;
}

void init(){
    mi[0] = 1;
    for(int i = 1; i < maxn; i++) {
        mi[i] = (mi[i - 1] << 1) % mod;
        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;
    }
    
    f[0] = 0, f[1] = 0;
    for(int i = 2; i < maxn; i++) {
        int fz = 0;
        for(int j = 0; j < i; j++)
            fz = (1ll * fz + (1ll * c[i][j] * f[j]) % mod) % mod;
        fz = (1ll * fz + 1ll * c[i][2] * mi[i-1]) % mod;
        f[i] = (1ll * fz * q_mod(mi[i] - 1 , mod - 2)) % mod;
       // cout << f[i] << " " << fz << endl;
    }
    
    for(int i = 1; i < maxn; i ++) {
        int res = 0;
        for(int j = 1; j <= i; j ++) 
            res = (1ll * res + f[j]) % mod;
        res = (1ll * res * q_mod(i, mod - 2) % mod);
        ans[i] = res;
    } 
    
}

signed main(){
    init();
    while(cin >> n) {
        cout << ans[n] << endl;
    }
    return 0;
}
全部评论

相关推荐

迟缓的斜杠青年巴比Q...:简历被投过的公司卖出去了,我前两天遇到过更离谱的,打电话来问我有没有意向报班学Java学习,服了,还拿我学校一个学长在他们那报班学了之后干了华为OD当招牌
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务