Everything Is Generated In Equal Probability
One day, Y_UME got an integer N and an interesting program which is shown below:
Y_UME wants to play with this program. Firstly, he randomly generates an integer n∈[1,N] in equal probability. And then he randomly generates a permutation of length n in equal probability. Afterwards, he runs the interesting program(function calculate()) with this permutation as a parameter and then gets a returning value. Please output the expectation of this value modulo 998244353.
A permutation of length n is an array of length n consisting of integers only ∈[1,n] which are pairwise different.
An inversion pair in a permutation p is a pair of indices (i,j) such that i>j and pi<pj. For example, a permutation [4,1,3,2] contains 4 inversions: (2,1),(3,1),(4,1),(4,3).
In mathematics, a subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements. Note that empty subsequence is also a subsequence of original sequence.
Refer to https://en.wikipedia.org/wiki/Subsequence for better understanding.
input
There are multiple test cases.
Each case starts with a line containing one integer N(1≤N≤3000).
It is guaranteed that the sum of Ns in all test cases is no larger than 5× 1 0 4 10^4 104
output
There are multiple test cases.
Each case starts with a line containing one integer N(1≤N≤3000).
It is guaranteed that the sum of Ns in all test cases is no larger than 5×
1
0
2
10^2
102
sample input
1
2
3
sample output
0
332748118
554580197
题目大意:
多组输入,给你一个N,在先在[1,N]之间随机选一个整数n,然后再从[1,n]之间随机选择一个数,构成一个长度为n的序列,然后将这个序列数组过一遍题目中给的那个程序,从calculate这个函数开始。
最后让求返回函数的期望是多少。
分析:
首
先
看
样
例
,
发
现
需
要
m
o
d
一
个
数
,
而
且
最
终
的
答
案
很
大
,
那
么
就
可
能
存
在
一
种
情
况
−
−
−
需
要
求
逆
元
…
…
…
…
。
{\color{Blue}首先看样例,发现需要mod一个数,而且最终的答案很大,那么就可能存在一种情况---需要求逆元…………。}
首先看样例,发现需要mod一个数,而且最终的答案很大,那么就可能存在一种情况−−−需要求逆元…………。
1.从[1,N]之间选择一个数,那么这个概率是
1
N
\frac{1}{N}
N1.
2.calculate这个函数返回的是逆序对对数,那么这样来考虑逆序对的对数,选择出来的长度为n的序列中从中选择两个数构成逆序对,那就是
C
n
2
C_n^2
Cn2,其概率就是
1
2
\frac{1}{2}
21.还有就是在递归选择子序列的过程中,如果这两个数出现在第i次递归中,那么概率就是
(
1
2
∗
(\frac{1}{2}*
(21∗
1
2
)
2
\frac{1}{2})^2
21)2
3.这样综合起来就是
1
N
∗
∑
k
=
1
N
(
C
k
2
∗
1
2
∗
∑
i
=
1
∞
(
1
2
∗
1
2
)
i
)
\frac{1}{N}*\sum_{k=1}^N (C_k^2*\frac{1}{2}*\sum_{i=1}^ \infty(\frac{1}{2}*\frac{1}{2})^i)
N1∗k=1∑N(Ck2∗21∗i=1∑∞(21∗21)i)
=
1
N
∗
∑
k
=
1
N
k
∗
(
k
−
1
)
/
3
=\frac{1}{N}*\sum_{k=1}^N k*(k-1)/3
=N1∗k=1∑Nk∗(k−1)/3
最后需要打一个表还有求逆元就好了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstring>
#include<set>
#include<queue>
#include<stack>
#include<map>
typedef long long ll;
using namespace std;
const ll mod=998244353;
ll epow(ll k){
ll ans=1;
ll p=mod-2;
while(p){
if(p&1)
ans=(ans*k)%mod;
k=(k*k)%mod;
p>>=1;
}
return ans;
}
ll ans[3010];
void init(){
ans[2]=2;
for(int i=3;i<=3000;i++){
ans[i]=((i*(i-1))+ans[i-1])%mod;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int n;
init();
while(scanf("%d",&n)!=EOF){
printf("%lld\n",(((ans[n]*epow(3))%mod)*epow(n))%mod);
}
return 0;
}
其实上面的那个式子还可以继续化简为
(
n
2
−
1
)
/
9
(n^2-1)/9
(n2−1)/9
https://zhidao.baidu.com/question/272976678.html
O(1)就可以求出
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstring>
#include<set>
#include<queue>
#include<stack>
#include<map>
typedef long long ll;
using namespace std;
const ll mod=998244353;
ll epow(ll k){
ll ans=1;
ll p=mod-2;
while(p){
if(p&1)
ans=(ans*k)%mod;
k=(k*k)%mod;
p>>=1;
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int n;
ll inv_9=epow(9);
while(scanf("%d",&n)!=EOF){
printf("%lld\n",((n*n-1)*inv_9)%mod);
}
return 0;
}