1. 程式人生 > >[UVALive - 7040]Color [容斥 恰好k個]

[UVALive - 7040]Color [容斥 恰好k個]

在這裡插入圖片描述

題意: 用m種顏色染一個線性格子,相鄰格子顏色不同,問恰好染k種顏色的方案數.
至多用k個顏色的方案數目為 k ( k 1 )

k * (k - 1)
但是要求的是恰好k個顏色,考慮容斥
A i A_i 表示不用 i
i號顏色
然後考慮對立面,
A 1
A 2 . . . A k | \overline{A_1} \cap \overline{A_2} \cap...\cap\overline{A_k} |
= k ( k 1 ) n 1 A 1 A 2 . . . A k =k * (k - 1)^{n-1} -|{A_1}\cup{A_2}\cup{...}\cup{A_k}|
= k ( k 1 ) n 1 A i + A i A j + . . . + ( 1 ) k A 1 A 2 . . . A k = k*(k-1)^{n-1}-\sum|A_i|+\sum|A_i\cap A_j|+...+(-1)^k\sum|A_1 \cap A_2\cap...\cap A_k|
A i = C k 1 ( k 1 ) ( k 2 ) n 1 \sum|A_i| = C_k^1*(k-1)*(k-2)^{n-1}
A i 1 A i 2 . . . A i j = C k j ( k j ) ( k j 1 ) n 1 \sum|A_{i_1} \cap A_{i_2}\cap...\cap A_{i_j}| = C_k^{j}*(k-j)*(k-j-1)^{n-1}
a n s = A 1 A 2 . . . A k C m k ans=| \overline{A_1} \cap \overline{A_2} \cap...\cap\overline{A_k} |*C_m^k
C m k C_{m}^{k} 可以利用遞推得到: C m k = C m k 1 m k + 1 k C_{m}^{k} = C_{m}^{k-1} * \frac {m-k+1}{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;
	}
	r