快速幂 + 逆元 + 组合数
题目链接
题解链接
快速幂求逆元
关键:求解 a / b (mod p) – a b 很大无法直接约分
利用x = a^{p-2} (mod p) [基于费马小定理] 使用前提使p必须为质数
否则 应该利用扩展欧几里得来求逆元。
#include <iostream>
#include <cstdio>
using namespace std;
#define LL long long
const int mod = 998244353;
int read()
{
int x = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-') w = -1;
ch = getchar();
}
while(ch <= '9' && ch >= '0')
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * w;
}
LL qpow(LL a, LL n) //计算a^n % mod 快速幂
{
LL x = 1;
while(n)
{
if(n & 1) //判断n的最后一位是否为1
{
x = (x * a) % mod;
}
n >>= 1; //舍去n的最后一位
a = (a * a) % mod; //将a平方
}
return x % mod;
}
LL ny(LL x) // 利用快速幂求逆元
{
return qpow(x, mod - 2);
}
LL C(int a, int b) // 求组合数
{
LL a1 = 1;
for(int i = a; i >= a - b + 1; i--)
{
a1 *= i;
a1 %= mod;
}
LL a2 = 1;
for(int i = 1; i <= b; i++)
{
a2 *= i;
a2 %= mod;
}
LL ni = ny(a2);
return (ni * a1) % mod;
}
int main()
{
int n, m;
cin >> n >> m;
LL c1 = C(m, n - 1);
LL c2 = C(n - 2, 1);
LL p = 1;
for(int i = 1; i <= n - 3; i++)
{
p *= 2;
p %= mod;
}
cout << ((c1 * c2) % mod * p) % mod;
return 0;
}