播放列表【容斥定理】
阿新 • • 發佈:2018-12-25
小Hi的手機中存著N首他喜愛的歌曲。現在小Hi希望製作一個長度為L的播放列表,滿足
1. 每一首歌至少播放一編
2. 同一首歌不能連續播放,之間至少間隔一首其他歌曲
請你計算一共有多少種不同的播放列表滿足條件?由於結果可能非常大,你只需要輸出結果模1000000009的餘數。
Input
兩個整數N和L。
對於30%的資料,1 ≤ N ≤ 5,N ≤ L ≤ 10
對於100%的資料,1 ≤ N ≤ 1000, N ≤ L ≤ 2000
Output
一個整數,代表答案。
Sample Input
3 4
Sample Output
18
一開始看成了1e9+7交了次罰時……
一道容斥的模板題吧,有N個喜歡的歌,還有L長度的選擇,那麼我們每次考慮的是選取這麼多的歌,然後會發現,有"abc"三種歌的時候,會選擇到"aba"這樣的情況,那麼顯然是不行的,那麼我們就要把選擇三種的可能中的只用了兩種的刪除掉,但是,刪完兩種,還要再考慮到只剩一種的情況是不是刪多了,所以,還要加上去,這樣一直處理到N為1時候就可以跳出了,並且,此時就是答案。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 1005; const int mod = 1e9 + 9; int N, L; ll jiecheng[maxN]; void pre_did() { jiecheng[0] = jiecheng[1] = 1; for(int i=2; i<maxN; i++) jiecheng[i] = jiecheng[i-1] * (ll)i%mod; } ll fast_mi(ll x, ll y) { ll ans = 1; while(y) { if(y & 1) ans = ans * x %mod; x = x * x % mod; y>>=1; } return ans; } ll Cal(ll down, ll up) { return jiecheng[down] * fast_mi(jiecheng[up], mod-2) %mod * fast_mi(jiecheng[down - up], mod - 2) %mod; } int main() { pre_did(); while(scanf("%d%d", &N, &L)!=EOF) { ll ans = 0; for(int i=0; i<N; i++) { ans = ( ans + ( ((i&1)==0)?1:(-1)) * Cal(N, N-i) * (N-i) %mod * fast_mi(N-i-1, L-1)%mod + mod )%mod; } printf("%lld\n", ans); } return 0; }