hdu多校第二場 1005 (hdu6595) Everything Is Generated In Equal Probability


題意:

給定一個N,隨機從[1,N]里產生一個n,然后隨機產生一個n個數的全排列,求出n的逆序數對的數量,加到cnt里,然后隨機地取出這個全排列中的一個非連續子序列(注意這個子序列可以是原序列),再求出這個子序列的逆序數對,加到cnt里,重復這個過程,直到最后取出的為空。

題解:

先不考慮第一步隨機從[1,N]里產生一個n,只考慮n給定的情況,求出了f[n],那么最后的結果就是

$  ans[N]=\frac{\sum_{n=1}^N f[n]}{N} $

賽時和隊友利用找規律法和暴力模擬法推出

$ f[i]=\sum_{i=1}^{n-1}\frac{2i}{3} $

下面給出證明:

因為任意一個長度為n的全排列,其所含的逆序對的期望為

$ \binom{n}{2}/2 $ (不難理解,就是隨便取兩個點交換一下就出來一個逆序對)

而取出的那一個非連續子序列,我們把它里面的數字離散化以后也是一個全排列,所以

$ f[i]=\binom{n}{2}/2+\frac{1}{2^i}\sum_{j=0}^i\binom{i}{j}f[j] $

移項,得到遞推公式

$ f[i]=\frac{2^{i-1}}{2^i-1}\binom{n}{2}/2+\frac{1}{2^i-1}\sum_{j=0}^{i-1}\binom{i}{j}f[j] $

f[1]=0,不難推出通項公式

$ f[i]=\sum_{i=1}^{n-1}\frac{2i}{3} $

代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
const int MOD = 998244353;
#define rep(i,n,m) for(int i=n;i<=m;++i)
const double eps = 1e-16;
#define ll long long
using namespace std;
const int maxn = 10000000;
const int maxm = 2e5 + 10;
const int inf = 1 << 28;
typedef pair<int, int> P;
#define zero(a) fabs(a)<eps
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = 10 * x + ch - '0';
        ch = getchar();
    }
    return x * f;
}


ll quick_mod(ll x, ll n) {
    ll res = 1;
    while (n) {
        if (n & 1) res = res * x % MOD;
        x = x * x % MOD;
        n = n >> 1;
    }
    return res;
}
ll a[3005];
void init()
{
    a[0] = a[1] = 0;
    a[2] = 2;
    for (int i = 3; i <= 3000; ++i)
        a[i] = a[i - 1] + (i - 1) * 2;
    for (int i = 1; i <= 3000; ++i)
        a[i] += a[i - 1];
}
int main()
{
    ll n;
    init();
    while (~scanf("%lld", &n))
    {
        if (n == 1) { cout << "0" << endl; continue; }
        ll a1 = a[n];
        ll b = 3 * n;
        ll x = quick_mod(b, MOD - 2);
        cout << a1 % MOD * x % MOD<<endl;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM