這裏補一下E題
解題思路:
- 這題自己沒寫出來,主要是不知道組合的板子
- 首先正常來推理思路
- 有n個點,m種顏色,然後最多有k個相鄰點可以使顏色相同
- 那麼對於k我們就可以分解成0 - k ,k + 1種情況
- 對於任何一個i (0 ~ k),我們都有
ans = m * C(n - 1,i) * (m - 1) ^ (n - i - 1)
- 這裏的m是第一個位置選顏色的個數,那麼後面的位都可以選用(m - 1) 個顏色,其中有i個位置的顏色與相鄰相同,所以我們選出這i個位置,其他的就有n - i - 1個位置 (那個 1 是第一位佔用的),然後根據這個式子,就可以求出(這裏的m可以提出)。
代碼:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int mod = 998244353, N = 200010;
ll fac[N], p[N];
ll inv[N];
ll mod_mult(ll a,ll b,ll m){ //計算 a*b
ll res = 0;
ll exp = a % m;
while(b){
if (b&1){
res += exp;
if (res > m) res -= m;
}
exp<<=1;
if (exp > m) exp -= m;
b>>=1;
}
return res;
}
ll mod_exp(ll a,ll b,ll m){
ll res = 1;
ll exp = a % m;
while(b){
if (b & 1) res = mod_mult(res,exp,m);
exp = mod_mult(exp,exp,m);
b>>=1;
}
return res;
}
ll C(int x, int y){
return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
int main(){
long long n, m, k;
scanf("%lld%lld%lld",&n,&m,&k);
long long ans = 0;
fac[0] = 1;
for (int i = 1; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
inv[n] = mod_exp(fac[n], mod - 2, mod);
for (int i = n ; i >= 0; i--) inv[i - 1] = 1ll * inv[i] * i % mod;
p[0] = 1;
for (int i = 1; i <= n; i++){
p[i] = p[i - 1] * (m - 1) %mod;
}
for (int i = 0; i <= k; i++){
long long num = C(n-1,i) % mod * p[n - i - 1] % mod;
ans = (ans + num) % mod;
}
printf("%lld\n",ans * m % mod);
return 0;
}