【JZOJ5931】氣泡排序
阿新 • • 發佈:2018-11-23
description
小 S 開始專注於研究⻓度為 n 的排列,他想知道,在你運氣足夠好的情況下(即每次氣泡排序的交換次數都是可能的最少交換次數,彷彿有上帝之手在操控),對於一個等概率隨機的長度為n 的排列,進行這樣的氣泡排序的期望交換次數是多少?
analysis
-
結論題
-
設 為 的答案,推 即可
-
插入 這個數,前 位都會產生 的代價,只有 位產生 的代價
-
把式子化一下就是
-
要用 求逆元
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 10000005
#define mod 998244353ll
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))
using namespace std;
ll f[MAXN],inv[MAXN];
ll n;
O3 inline ll read()
{
ll x=0,f=1;
char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
O3 int main()
{
freopen("inverse.in","r",stdin);
freopen("inverse.out","w",stdout);
f[1]=0,inv[1]=1;
fo(i,2,MAXN)inv[i]=(mod-mod/i)*1ll*inv[mod%i]%mod,f[i]=((f[i-1]+(i-1)*inv[i])%mod+mod)%mod;
n=read();
while (n--)printf("%lld\n",f[read()]);
return 0;
}