CodeForces - 1312D. Count the Arrays
Address original title:
http://codeforces.com/contest/1312/problem/D
The basic meaning of the questions:
Calculation of the number of array meet the following conditions:
- Array has n elements
- Array element value between 1 - m
- For each array has one and only one pair of equal elements (I am an English mental retardation, this has not exactly get to know)
- There is an array meet a strictly increasing at position i left i, the right strictly decreasing
The answer modulo 998 244 353;
The basic idea:
- We are looking for simultaneously satisfy the condition (3) (4) of the array, as long as we [1, m] to find the pick n - 1 number of them strictly ascending;
- Then, in order to satisfy the condition (3) again in addition to the highest i.e. that the remaining n - 2 a pick as the one on the right side in duplicate;
- Finally, the remaining n-3 may be arbitrarily picked number where the i-th on the right side (i = 1,2,3, ..., n-3).
So to sum up the answer:
mod_comb(m, n-1,mod) * mod_comb(n - 2, 1,mod) * 2 ^ (n-3) % mod
Reference Code:
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false)
#define int long long
#define INF 0x3f3f3f3f
const int maxn = 2e5+10;
int fact[maxn];
inline int qsm(int x,int n,int mod) {
int res = 1;
while (n > 0) {
if (n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
inline int extgcd(int a,int b,int &x,int &y) {
int d = a;
if (b != 0) {
d = extgcd(b, a % b, y, x);
y -= (a / b) * x;
} else {
x = 1;
y = 0;
}
return d;
}
inline int mod_inverse(int a,int m) {
int x, y;
extgcd(a, m, x, y);
return (m + x % m) % m;
}
inline int mod_fact(int n,int p,int &e) {
e = 0;
if (n == 0) return 1;
int res = mod_fact(n / p, p, e);
e += n / p;
if (n / p % 2 != 0) return res * (p - fact[n % p] % p);
return res * fact[n % p] % p;
}
inline int mod_comb(int n,int k,int p) {
if (n < 0 || k < 0 || n < k) return 0;
int e1, e2, e3;
int a1 = mod_fact(n, p, e1), a2 = mod_fact(k, p, e2), a3 = mod_fact(n - k, p, e3);
if (e1 > e2 + e3) return 0;
return a1 * mod_inverse(a2 * a3 % p, p) % p;
}
const int mod = 998244353;
int n,m;
signed main() {
IO;
fact[0] = 0, fact[1] = 1;
for (int i = 2; i <= maxn; i++) fact[i] = fact[i - 1] * i % mod;
cin >> n >> m;
if (n == 2) {
cout << 0 << endl;
return 0;
}
int ans = mod_comb(m, n - 1, mod);
ans %= mod;
ans *= n - 2;
ans %= mod;
ans *= qsm(2, n - 3, mod);
ans %= mod;
cout << ans << endl;
return 0;
}