F. Card Bag
You have a bag which contains n cards. There is a number written on each card; the number on iii-th card is aia_iai.
You are playing the following game. During each turn, you choose and remove a random card from the bag (all cards that are still left inside the bag are chosen equiprobably). Nothing else happens during the first turn — but during the next turns, after removing a card (let the number on it be xxx), you compare it with the card that was removed during the previous turn (let the number on it be yyy). Possible outcomes are:
if x<yx<yx<y, the game ends and you lose;
if x=yx=yx=y, the game ends and you win;
if x>yx>yx>y, the game continues.
If there are no cards left in the bag, you lose. Cards are not returned into the bag after you remove them.
You have to calculate the probability of winning in this game. It can be shown that it is in the form of PQ\frac{P}{Q}QP where P and Q are non-negative integers and Q !=0,P≤QQ\ != 0, P\leq QQ !=0,P≤Q. Output the value of P⋅Q−1P⋅Q^{−1}P⋅Q−1 (mod 998244353)(mod\ 998244353)(mod 998244353).
Input
The first line contains one integer n(2≤n≤5000)n (2\leq n\leq5000)n(2≤n≤5000) — the number of cards in the bag.
The second live contains nnn integers a1,a2,…an(1≤ai≤n)a_1,a_2,…a_n (1≤a_i≤n)a1,a2,…an(1≤ai≤n) — the iii-th integer is the number written on the iii-th card.
Output
Print one integer — the probability of winning in this game modulo 998244353998244353998244353.
Examples
input
5
1 1 4 2 3
output
299473306
input
2
2 2
output
1
input
5
4 5 1 3 2
output
0
input
4
1 3 4 3
output
748683265
Note
In the first test case the probability of winning is 110\frac{1}{10}101.
In the second test case the probability of winning is 1.
In the third test case the probability of winning is 0.
In the fourth test case the probability of winning is 14\frac{1}{4}41.
题意:
- 包里面有nnn个数,每次取一个数,当前取出的数为xxx,前一个取出的数为yyy,则:
- 若x>yx>yx>y,游戏继续
- 若x=yx=yx=y,游戏结束并且玩家赢
- 若x<yx<yx<y,游戏结束并且玩家输
问玩家赢的概率
解法:
- 统计每个数的个数,从小到大依次记为b1,b2...blenb_1,b_2...b_{len}b1,b2...blen其中lenlenlen为数的种数,且b1<b2<...<blenb_1<b_2<...<b_{len}b1<b2<...<blen,对应的个数分别为cnt1,cnt2...cntlencnt_1,cnt_2...cnt_{len}cnt1,cnt2...cntlen,然后从左往右扫一遍,若当前的cnti≥2cnt_i\geq2cnti≥2则可能对答案构成贡献,计算这个贡献就要用排列组合了
- 首先从cnticnt_icnti中选出两个数并排列,作为最后取的两个,方案为Acnti2A_{cnt_i}^{2}Acnti2
- 设当前枚举的是bbb中的第iii个,然后考虑这两个数的前面放多少个数(显然前面的这些数小于当前枚举的数,而且只能递增放置,每个数最多放一个),枚举个数(假设为jjj个),那么问题是怎么知道从比bib_ibi小的所有数中选出j−1j-1j−1个满足上述条件的方案数呢?这是可以用一个背包dp[i][j]表示从前i个选出j个不同的数的方案数,那么有如下转移方程:
dp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗cntidp[i][j]=dp[i-1][j]+dp[i-1][j-1]*cnt_idp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗cnti - 然后把剩下的没有选上的统统放到后面就行了,(当然这些数要排列一下)
上述三个结果想乘就是当前位构成的贡献,然后把所有的相加就是总贡献,除以n!n!n!就是赢的概率
附代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
int n, a[5005], cnt[5005];
int num[5005], len = 0;
ll fac[5005];
ll dp[5005][5005];
ll quick_pow(ll a, ll b)
{
ll res = 1ll;
while(b){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
cnt[a[i]]++;
}
fac[0] = 1ll;
for(int i = 1; i <= 5004; i++) fac[i] = fac[i - 1] * i % mod;
for(int i = 1; i <= 5004; i++) if(cnt[i]){
num[++len] = i;
cnt[len] = cnt[i];
}
ll ans = 0ll;
for(int i = 0; i <= len; i++) dp[i][0] = 1ll;
for(int i = 1; i <= len; i++){
for(int j = 1; j <= i; j++){
dp[i][j] = (dp[i - 1][j - 1] * cnt[i] + dp[i - 1][j]) % mod;
}
}
for(int i = 1; i <= len; i++){
if(cnt[i] >= 2){
for(int j = i; j >= 1; j--){
ans = (ans + ((dp[i - 1][j - 1] * cnt[i] * (cnt[i] - 1)) % mod * fac[n - 2 - j + 1] % mod)) % mod;
}
}
}
ans = ans * quick_pow(fac[n], mod - 2) % mod;
printf("%lld\n", ans);
}