题意:
题意很明确,n个值,两个人轮流取,问有多少种可能,然后取模。
这个题意看看样例应该很好理解
分析
首先统计一下每个数的个数,然后顺序排好,就没有问题了。
我推出的第一条性质是如果存在一个奇数个的大数,那么它一定会比这个数下面的数先被取走,偶数个数的大数,乃至偶数个的任何数都没有这个性质。
由此再考虑偶数个的数字,我们发现偶数取的规律十分随意,但是呢,有一个很抽象的性质,对于后手来说,先手如果取了一个偶数个数的数,那么我作为后手一定会去选择一个比你大或者等于你的偶数的数,这里的前提是没有个数的数了,因为前面说了,奇数一定在此之前就被取走了;(感性理解的话,这些数都是成对的,你拿啥我拿啥,甚至我拿的比你还大,那么两个人都用此策略,是完全不会影响答案的)理解之后发现规律,把对相同的偶数看作括号,则上面和下面的不能相交,也就是如果有3 ,3 ,4 ,4 四个数字,我如果拿3,你拿4我肯定不能拿3 了,这样就是相交,3,4,4,3就是包含,就是不相交的情况。其次呢,对于成对的大数,要么与小数并列,要么被小数的括号包含起来。
考虑这样的状态数,从小到大遍历,把成对的大数一起放,下面的小数是可以放进小数中间的,也就是放4,4 的时候,可以放成3,3,4,4或者4,4,3,3或者3,4 ,4,3;但是大的是在一起的,小数是可以分开的。
所以这样的话,我们考虑每个数往里放的贡献,累乘起来就好了。
这里挂出来官方题解:
首先ci!是肯定大家都知道的,然后每次后面的组合公式的意思是,对于每次往里放大数的时候,成对的放,就有ci/2取整对,然后考虑到放完之后会有
种状态,那么从中选出ci/2种作为放入的序列,然后再乘上阶乘就是每次的答案,累乘起来就是结果。
#include <bits/stdc++.h>
#define ll long long
const ll mod = 998244353;
const ll p = 998244353;
const ll N = 2e6 + 1000;
using namespace std;
ll arr[N];
ll ux[N];
vector<ll> st;
typedef long long LL;
LL n, m;
LL quick_mod(LL a, LL b) {
LL ans = 1;
a %= p;
while (b) {
if (b & 1) {
ans = ans * a % p;
b--;
}
b >>= 1;
a = a * a % p;
}
return ans;
}
LL C(LL n, LL m) {
if (m > n) return 0;
LL ans = 1;
for (int i = 1; i <= m; i++) {
LL a = (n + i - m) % p;
LL b = i % p;
ans = ans * (a * quick_mod(b, p - 2) % p) % p;
}
return ans;
}
LL Lucas(LL n, LL m) {
if (m == 0) return 1;
return C(n % p, m % p) * Lucas(n / p, m / p) % p;
}
inline void solve() {
ux[0] = 1;
for (ll i = 1; i <= 1000009; i++) {
ux[i] = ux[i - 1] * i;
ux[i] %= mod;
}
ll n;
scanf("%lld", &n);
for (ll i = 0; i < n; i++) {
scanf("%lld", &arr[i]);
}
sort(arr, arr + n);
ll cnt = 1;
for (ll i = 1; i < n; i++) {
if (arr[i] == arr[i - 1])
cnt++;
else
st.push_back(cnt), cnt = 1;
}
st.push_back(cnt);
ll t = 0, ans = 1;
for (ll i = 0; i < st.size(); i++) {
int uu=st[i]/2;
ans*=Lucas(uu+t,uu);
ans%=mod;
ans*=ux[st[i]];ans%=mod;
t+=st[i];
}
printf("%lld\n", ans % mod);
}
int main() {
solve();
return 0;
}