• 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
    ", 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
    ",Case,ans*CM%MOD);
    103 
    104     }
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    Python面向对象详解
    使用树莓派搭建LoRaWAN网关并接入腾讯云物联网开发平台
    dajngo
    dajngo 项目目录结构调整
    Django
    nacos的简单使用
    MySQL数据库开发规范
    mabatis的sql标签
    直接插入100w数据报错
    大数据量插入到数据库
  • 原文地址:https://www.cnblogs.com/mengchunchen/p/4851306.html
Copyright © 2020-2023  润新知