日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces 100548F - Color (组合数+容斥)

發布時間:2024/10/12 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces 100548F - Color (组合数+容斥) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:http://codeforces.com/gym/100548/attachments

有n個物品 m種顏色,要求你只用k種顏色,且相鄰物品的顏色不能相同,問你有多少種方案。

從m種顏色選k種顏色有C(m, k)種方案,對于k種顏色方案為k*(k-1)^(n-1)種。但是C(m, k)*k*(k-1)^(n-1)方案包括了選k-1,k-2...,2種方案。

題目要求剛好k種顏色,所以這里想到用容斥。

但是要是直接C(m, k)*k*(k-1)^(n-1) - C(m, k-1)*(k-1)*(k-2)^(n-1)的話,其實是多減的。

比如k=4,4種顏色1 2 3 4,有種染色方案是1 2 1 2,那么k-1的話1 2 3或者1 2 4也有染色方案是1 2 1 2,這里發現多減了。所以k-2還得加上。

所以公式就變成了

C(m, k)*( k*(k-1)^(n-1) - C(k, k-1)*(k-1)*(k-2)^(n-1)?+ C(k, k-2)*(k-2)*(k-3)^(n-1) ... )

中間的組合數C(k, i),可以用逆元來解決。C(m, k)則暴力即可。

1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime> 10 #include <list> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef __int64 LL; 15 typedef pair <int, int> P; 16 const int N = 1e6+ 5; 17 LL mod = 1e9 + 7; 18 LL f[N]; 19 20 LL Pow(LL a , LL n , LL mod) { 21 LL res = 1; 22 while(n) { 23 if(n & 1) 24 res = res * a % mod; 25 a = a * a % mod; 26 n >>= 1; 27 } 28 return res; 29 } 30 31 LL Cnm(LL n, LL m, LL mod) { 32 if(n < N) { //數據范圍小的 逆元就好了 33 return f[n]*Pow(f[m]*f[n-m]%mod, mod - 2, mod) % mod; 34 } 35 LL res = Pow(f[m]%mod, mod - 2, mod)%mod; 36 for(LL i = 0; i < m; ++i) { 37 res = res * (n-i) % mod; 38 } 39 return res%mod; 40 } 41 42 void init() { //階乘預處理 43 f[0] = 1; 44 for(LL i = 1; i < N; ++i) 45 f[i] = f[i - 1] * i % mod; 46 } 47 48 int main() 49 { 50 init(); 51 int t; 52 LL n, m, k; 53 scanf("%d", &t); 54 for(int ca = 1; ca <= t; ++ca) { 55 scanf("%lld %lld %lld", &n, &m, &k); 56 printf("Case #%d: ", ca); 57 if(k == 1 && n == 1) { 58 printf("%lld\n", m); 59 continue; 60 } 61 else if(k == 1) { 62 printf("0\n"); 63 continue; 64 } 65 LL ans = 0, temp = k; 66 for(int i = 1; k >= 2; --k, i = -i) { 67 ans = (i * Cnm(temp, k, mod) % mod *k % mod* Pow(k- 1, n - 1, mod) % mod + ans) % mod; 68 } 69 ans = ans * Cnm(m, temp, mod) % mod; 70 printf("%lld\n", (ans + mod) % mod); 71 } 72 return 0; 73 } View Code

之前糾結了好久...

轉載于:https://www.cnblogs.com/Recoder/p/5773486.html

總結

以上是生活随笔為你收集整理的Codeforces 100548F - Color (组合数+容斥)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。