版权声明:将来的你一定会感谢现在努力的你!!!! https://blog.csdn.net/qq_37383726/article/details/83188883
题意: 用m种颜色染一个线性格子,相邻格子颜色不同,问恰好染k种颜色的方案数.
至多用k个颜色的方案数目为
但是要求的是恰好k个颜色,考虑容斥
表示不用
然后考虑对立面,
可以利用递推得到:
代码
/***********************************************
Author :lzs
Created Time :2018年10月19日 星期五 17时49分21秒
File Name :Color.cpp
************************************************/
#include <bits/stdc++.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define rep(i, l, r) for(int i = l; i < r; i++)
#define per(i, r, l) for(int i = r; i >= l; i--)
#define dbgln(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<"\n"
#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>pii;
const int N = (int) 1e6 + 20;
const int M = (int) 1e6 + 11;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 0x3f3f3f3f;
const ll INFF = (ll) 0x3f3f3f3f3f3f3f3f;
/*-----------------------------------------------------------*/
int Pow(int a, int b, int c = MOD){
int s = 1; a %= c;
while(b){
if(b & 1) s = s * 1ll * a % c;
b >>= 1;
a = a * 1ll * a % c;
}
return s;
}
int fac[N], inv[N], in[N];
void ini(int n){
fac[0] = 1;
for(int i = 1; i < n; i++) fac[i] = i * 1ll * fac[i - 1] % MOD, in[i] = Pow(i, MOD - 2);
inv[n - 1] = Pow(fac[n - 1], MOD - 2); inv[0] = 1;
for(int i = n - 2; i > 0; i--) inv[i] = inv[i + 1] * 1ll * (i + 1) % MOD;
}
int C(int n, int m){
if(n < m) return 0;
return fac[n] * 1ll * inv[n - m] % MOD * inv[m] % MOD;
}
int main(){
ini(1000000 + 10);
int T; scanf("%d" ,&T);
for(int cas = 1; cas <= T; cas++){
int n, m, k; scanf("%d%d%d", &n, &m, &k);
int cmk = 1;
for(int i = 1; i <= k; i++)
cmk = cmk * 1ll * (m - i + 1) % MOD * in[i] % MOD;
ll ans = k * 1ll * Pow(k - 1, n - 1) % MOD;
int cur = -1;
for(int i = 1; i < k; i++){
ans += cur * 1ll * C(k, i) * (k - i) % MOD * Pow(k - i - 1, n - 1) % MOD;
ans = (ans + MOD) % MOD;
cur = -cur;
}
ans = ans * 1ll * cmk % MOD;
printf("Case #%d: %lld\n", cas, ans);
}
return 0;
}