CF GYM100548 (相邻格子颜色不同的方案数 2014西安区域赛F题 容斥原理)

n个格子排成一行,有m种颜色,问用恰好k种颜色进行染色,使得相邻格子颜色不同的方案数。

integers n, m, k (1 ≤n, m ≤ 10^9, 1 ≤ k ≤ 10^6, k ≤ n, m).

m种颜色取k种 C(m, k) 这个可以放最后乘 那么问题就变成只用k种颜色
第一个格子有k种涂法 第二个有k-1种 第三个也是k-1种

一共就是k*(k-1)^(n-1) 这种算法仅保证了相邻颜色不同,总颜色数不超过k种,并没有保证恰好出现k种颜色 也就是多算了恰好出现2种 恰好出现3种.... 恰好出现k-1种

我们本来是要求 恰好用k的种 现在又要求恰好出现k-1种
那么就是 (k-1)*(k-2)^(n-1) 然后这个也是多算了一些情况的
以此类推 然后就可以用容斥原理

比如有5种颜色,选4种 就是

C(5, 4) * (C(4, 4)*4*3^4 - C(4, 3)*3*2^4 + C(4, 2)*2*1^4)

Sample Input

2
3 2 2// n m k
3 2 1
Sample Output

Case #1: 2
Case #2: 0

  1 # include <iostream>
  2 # include <cstdio>
  3 # include <cstring>
  4 # include <algorithm>
  5 # include <string>
  6 # include <cmath>
  7 # include <queue>
  8 # include <list>
  9 # define LL long long
 10 using namespace std ;
 11
 12 const int MOD = 1000000007 ;
 13
 14 int n , m  , k ;
 15 LL CM ;
 16 LL CK[1000010] ;
 17 LL INV[1000010] ;
 18
 19
 20 LL pow_mod(LL p, LL k)
 21 {
 22     LL ans = 1;
 23     while(k) {
 24         if (k & 1) ans = ans * p % MOD;
 25         p = (LL)p*p % MOD;
 26         k >>= 1;
 27     }
 28     return ans;
 29 }
 30
 31 LL Ext_gcd(LL a,LL b,LL &x,LL &y){  //扩展欧几里德
 32    if(a==0&&b==0) return -1;
 33    if(b==0) { x=1, y=0; return a; }
 34    LL d= Ext_gcd(b,a%b,y,x);
 35    y-= a/b*x;
 36    return d;
 37 }
 38 //ax = 1(mod m)
 39 LL Inv(LL a,LL m){   //求逆元  a对m的逆元
 40    LL d,x,y,t = m;
 41    d= Ext_gcd(a,t,x,y);
 42    if(d==1) return (x%t+t)%t;
 43    return -1;
 44 }
 45
 46
 47 LL Cm(LL n, LL m, LL p)  //求组合数
 48 {
 49     LL a=1, b=1;
 50     if(m>n) return 0;
 51     while(m)
 52     {
 53         a=(a*n)%p;
 54         b=(b*m)%p;
 55         m--;
 56         n--;
 57     }
 58     return (LL)a*Inv(b,p)%p;  //(a/b)%p 等价于 a*(b,p)的逆元
 59 }
 60
 61 int Lucas(LL n, LL m, LL p)  //把n分段递归求解相乘
 62 {
 63     if(m==0) return 1;
 64     return (LL)Cm(n%p,m%p,p)*(LL)Lucas(n/p,m/p,p)%p;
 65 }
 66
 67 void init()
 68 {
 69     INV[1] = 1 ;
 70     int i ;
 71     for (i = 2 ; i < 1000010 ; i++)
 72         INV[i] = Inv(i,MOD) ;
 73 }
 74
 75 int main()
 76 {
 77     //freopen("in.txt","r",stdin) ;
 78     int T ;
 79     scanf("%d" , &T) ;
 80     int Case = 0 ;
 81     init() ;
 82     while(T--)
 83     {
 84         Case++ ;
 85         scanf("%d%d%d" , &n , &m , &k) ;
 86         if (n == 1)
 87         {
 88             printf("Case #%d: %d\n", Case , m);
 89             continue ;
 90         }
 91         int i ;
 92         CM = Cm(m,k,MOD) ;
 93         CK[0] = 1 ;
 94         for (i = 1 ; i <= k ; i++)
 95             CK[i] = (CK[i-1] * (k-i+1)%MOD * INV[i])%MOD ;
 96         LL ans = 0 , t = 1 ;
 97         for (i = k ; i >= 2 ; i--)
 98         {
 99             ans = (ans + t*CK[i]*i%MOD*pow_mod(i-1,n-1)%MOD+MOD)%MOD ;
100             t *= -1 ;
101         }
102         printf("Case #%d: %I64d\n",Case,ans*CM%MOD);
103
104     }
105     return 0;
106 }

时间: 2024-10-05 13:17:45

CF GYM100548 (相邻格子颜色不同的方案数 2014西安区域赛F题 容斥原理)的相关文章

CF GYM 100548 The Problem Needs 3D Arrays(2014ACM西安现场赛Problem C)

ProblemC. The Problem Needs 3D Arrays Description A permutation is asequence of integers p1, p2, . . . , pn,consisting of n distinct positive integers and each of them does notexceed n. Assume that r(S) of sequence S denotes the number ofinversions i

Party at Hali-Bula(树形DP+判断方案数是否唯一)

Party at Hali-Bula UVA - 1220 题意: 公司里有n(n<=200)个人形成一个树状结构, 要求尽量选多的人,但不能同时选择一个人和他的直属上司,文最多能选多少人,以及是否方案唯一. 1 //dp[x][0]表示不选X节点能达到的最大人数,dp[x][1]表示选x节点的最大人数 2 //f数组含义和dp基本一致,f[x][0]表示如果不选x节点是否方案数唯一 f[x][1]表示如果选x节点方案数是否唯一 3 //如果f数组为1表示方案数不唯一 4 //对于一个根节点,如

CF GYM 100548 Color(2014ACM西安现场赛Problem F)

ProblemF. Color Description Recently, Mr. Bigrecieved n flowers from his fans. He wants to recolor those flowerswith m colors. The flowers are put in a line. It is not allowed tocolor any adjacent flowers with the same color. Flowers i and i + 1are s

poj 3734 方块涂色 求红色 绿色方块都为偶数的方案数 (矩阵快速幂)

N个方块排成一列 用红,蓝,绿,黄4种颜色去涂色,求红色方块 和绿色方块个数同时为偶数的 方案数 对10007取余 Sample Input 212Sample Output 2//(蓝,黄)6//(红红,蓝蓝,蓝黄,绿绿,黄蓝,黄黄) 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <map>

(hdu step 3.1.6)统计问题(求不断地左右走、向上走n步的方案数)

在写题解之前给自己打一下广告哈~..抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下: http://edu.csdn.net/course/detail/209 题目: 统计问题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 732 Accepted Submission(s): 466   Problem Description

UVa 11137 (完全背包方案数) Ingenuous Cubrency

题意:用13.23……k3这些数加起来组成n,输出总方案数 d(i, j)表示前i个数构成j的方案数则有 d(i, j) = d(i-1, j) + d(i, j - i3) 可以像01背包那样用滚动数组来实现 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 10; 8

洛谷P1108 低价购买[DP | LIS方案数]

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数. 这里是某支股票的价格清单: 日期 1 2

NOIP2012pj摆花[DP 多重背包方案数]

题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列. 试编程计算,一共有多少种不同的摆花方案. 输入输出格式 输入格式: 第一行包含两个正整数n和m,中间用一个空格隔开. 第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1.a2.……an. 输出格式: 输出只有一行,一个整数

hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)

n个点 m条路 询问T次 从a点走到b点刚好k步的方案数是多少 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值把 给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就 等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数 Sample Input4 4 // n m0 10 21 32 32 //T0 3 2