UVALive 7040 Color (容斥原理 + 组合数学递推公式 + 求逆元 + 基础数论)
来源:互联网 发布:做金融网络销售赚钱吗 编辑:程序博客网 时间:2024/04/30 10:50
传送门
英文题目:
Recently, Mr. Big recieved n owers from his fans. He wants to recolor those owers with m colors. The
owers are put in a line. It is not allowed to color any adjacent owers with the same color. Flowers i and
i + 1 are said to be adjacent for every i, 1 ≤ i < n. Mr. Big also wants the total number of different
colors of the n owers being exactly k.
Two ways are considered different if and only if there is at least one ower being colored with different
colors.
插图:
题目大意:
首先有T组数据,每组数据有 3 个数 n, m, k,分别代表一共有 n 个方格,m种颜色,而我们要 恰好(注意是恰好) 使用 k 中颜色对这些方格进行涂色,并且保证的是每两个相邻的方格的颜色必须是不一样的。
解题思路:
首先拿过这个题来 不要急着就是说一眼就做出来,所以我们先对它分析一下,我们要从 m 种颜色中选出 k 个进行涂色 所以用的方法数就是 C(m,k),然后对这 n 个方格涂色,第一个 有 k 种选择, 而后边的 n-1 个方格中只有 k-1 种选择,所以 就有公式
然后这并不是最后的结果,这是 所选的颜色不超过 k 种的方法数,而不是 恰好 用 k 种颜色的,然后就可以用容斥原理来求了,假设集合 Ai 表示 i 号颜色不被选,所以 我们要求的结果
A1 ⋃ A2 ⋃… ⋃ An 就得通过容斥原理来做啦。。。
根据上面我们可以求出从 k 种颜色种选 k-i个,剩下的就是 n-1个方格中有 k-i-1中选择。所以这个公式就是:
然后考虑的就是奇数加 偶数减就行了。然后再注意一下细节问题:
1.怎么样求C(m,k),这个就是用到 递推公式了首先给出一个公式
这个公式很好推导:
所以根据这个公式我们可以打个表就能算 C(m,k)和 C(k,i)了
2.求逆元的问题。因为 C(x,i)=C(x,i-1)*(x-i+1)/i可以通过扩展欧几里得算法来算,但是要记得的是要用一个数组保存一下 每一个的逆元,要不然每次调用函数的话 会超时。
3.就是容斥的详细过程了。记住一点 奇数加偶数减就行
接下来就是编写程序了,详见我的代码。
My Code:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int MOD = 1e9+7;const int MAXN = 1e6+5;typedef long long LL;LL Scan()///输入外挂{ LL res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res;}void Out(LL a)///输出外挂{ if(a>9) Out(a/10); putchar(a%10+'0');}///快速幂LL quick_mod(LL a, LL b){ LL ans = 1; while(b) { if(b & 1) ans = ans*a%MOD; b>>=1; a = a*a%MOD; } return ans;}///求逆元void Exgcd(LL a, LL b, LL &x, LL &y){ if(b == 0) { x = 1; y = 0; return; } LL x1, y1; Exgcd(b, a%b, x1, y1); x = y1; y = x1 - (a/b)*y1;}LL Inv[MAXN];///放逆元的数组///得到逆元void Get_Inv(){ Inv[1] = 1; for(int i=2; i<MAXN; i++) { LL y; Exgcd(i, MOD, Inv[i], y); Inv[i] = (Inv[i]%MOD+MOD)%MOD; }}/** 得到组合数,通过递推公式 C(m,i) = C(m,i-1)*(m-i+1)/i; **/LL cm[MAXN], ck[MAXN];///分别是m的组合数 和 k 的组合数LL n, m, k;void Get_Fac(){ cm[0] = ck[0] = 1; for(int i=1; i<=k; i++) { cm[i] = (cm[i-1]%MOD * (m-i+1)%MOD * Inv[i]%MOD) % MOD; ck[i] = (ck[i-1]%MOD * (k-i+1)%MOD * Inv[i]%MOD) % MOD; }}/**111000000000 1000000000 1000000**/int main(){ Get_Inv(); int T; T = Scan(); for(int cas=1; cas<=T; cas++) { n = Scan(); m = Scan(); k = Scan(); Get_Fac(); LL ret = 1; LL ans = 0; for(LL i=k; i>=1; i--) { ans = (ans+ret*i*ck[i]%MOD*quick_mod(i-1,n-1)%MOD+MOD)%MOD; ret = -ret; //cout<<ans<<" "; } ans = ans * cm[k] % MOD; printf("Case #%d: %lld\n",cas,ans); } return 0;}
- UVALive 7040 Color (容斥原理 + 组合数学递推公式 + 求逆元 + 基础数论)
- UVALive 7040 Color (容斥原理 + 组合数学递推公式 + 求逆元 + 基础数论)
- UVALive 7040 Color 容斥原理 + 组合数学递推公式 +lucas
- UVALive 7040 Color 容斥,组合数递推,线形逆元,基础数论
- UVALive 7040 color(容斥原理)
- UVALive 7040 Color (容斥定理 + 递推求逆元 + 组合数 + 快速幂)
- UVALive 6469 Deranged Exams 组合数学+容斥原理
- HDU 1695 GCD (数论-整数和素数,组合数学-容斥原理)
- HDU 1695 GCD (数论-整数和素数,欧拉函数,组合数学-容斥原理)
- bzoj 3129: [Sdoi2013]方程(容斥原理+组合数学+数论)
- hdu6143Killer Names(组合递推+容斥原理)
- 容斥原理(组合数学)总结
- 2014ACM/ICPC亚洲区西安站 F题 color (组合数学,容斥原理)
- 51nod 序列变换 [容斥原理+莫比乌斯函数]【数论+组合数学】
- 20160331 UVA11806 Cheerleaders(组合数公式+容斥原理)
- 数学基础-容斥原理
- UVa 11806 - Cheerleaders (组合数学 容斥原理)
- uva 10325 The Lottery(组合数学-容斥原理)
- CCF之消除类游戏
- POJ 2251 Dungeon Master bfs
- 近 100 个 Linux 常用命令大全
- spring@value注入spel表达式
- VS2013MFC对话框工程学习笔记十一 - 动态改变一个控件标题
- UVALive 7040 Color (容斥原理 + 组合数学递推公式 + 求逆元 + 基础数论)
- 【FFmpeg学习笔记004】 视音频数据处理入门
- BZOJ3207: 花神的嘲讽计划Ⅰ
- spring schema介绍
- Gateone
- jrtplib—VS2013 win7 下RTP开源协议库JRTPLIB3.9.1编译
- kmp算法理解
- leetcode之Palindrome Number
- 流媒体传输协议(rtp/rtcp/rtsp/rtmp/mms/hls)