zoukankan      html  css  js  c++  java
  • uva 11916 Emoogle Grid

    题意:用K种颜色给一个N*M的格子涂色。其中有B个格子是不能涂色的。涂色时满足同一列上下紧邻的两个格子的颜色不同。所有的涂色方案模100000007后为R。现在给出M、K、B、R,求一个最小的N,满足题意。

    思路:分成两个部分。设给出的B个不能涂的格子的最大行坐标为m。 首先,我们能计算出前m行的方案数cnt,若cnt=r,则m就是答案。每增加一行,就会增加(K-1)^m种方法,接着令p=(K-1)^M,我们能计算出前m+1行的方案数cnt,若cnt=r 则答案为 m+1。否则,设下面还需要t行,那么有cnt*(p)^t%100000007=R,将cnt的逆元乘到右侧得到新的 p^t=R*reverse(cnt)。那么就成了求最小的t满足p^t%100000007=R*reverse(cnt)

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cmath>
      4 #include<set>
      5 #include<map>
      6 using namespace std;
      7 
      8 const int MOD = 100000007;
      9 const int maxb = 500 + 10;
     10 int n, m, k, b, r, x[maxb], y[maxb];
     11 set<pair<int, int> > bset;
     12 
     13 int pow_mod(int a, long long p)
     14 {
     15     if(p == 0) 
     16         return 1;
     17     int ans = pow_mod(a, p/2);
     18     ans = (long long)ans * ans % MOD;
     19     if(p%2) 
     20         ans = (long long)ans * a % MOD;
     21     return ans;
     22 }
     23 
     24 int mul_mod(int a, int b)
     25 {
     26     return (long long)a * b % MOD;
     27 }
     28 
     29 int inv(int a)
     30 {
     31     return pow_mod(a, MOD-2);
     32 }
     33 
     34 int log_mod(int a, int b)
     35 {
     36     int m, v, e = 1, i;
     37     m = (int)sqrt(MOD);
     38     v = inv(pow_mod(a, m));
     39     map <int,int> x;
     40     x[1] = 0;
     41     for(i = 1; i < m; i++)
     42     {
     43         e = mul_mod(e, a);
     44         if (!x.count(e)) x[e] = i;
     45     }
     46     for(i = 0; i < m; i++)
     47     {
     48         if(x.count(b)) return i*m + x[b];
     49         b = mul_mod(b, v);
     50     }
     51     return -1;
     52 }
     53 
     54 // 计算可变部分的方案数
     55 int count()
     56 {
     57     int c = 0; // 有k种涂法的格子数
     58     for(int i = 0; i < b; i++)
     59     {
     60         if(x[i] != m && !bset.count(make_pair(x[i]+1, y[i]))) c++; // 不可涂色格下面的可涂色格
     61     }
     62     c += n; // 第一行所有空格都有k种涂法
     63     for(int i = 0; i < b; i++)
     64         if(x[i] == 1) c--; // 扣除那些不能涂色的格子
     65 
     66     // ans = k^c * (k-1)^(mn - b - c)
     67     return mul_mod(pow_mod(k, c), pow_mod(k-1, (long long)m*n - b - c));
     68 }
     69 
     70 int doit()
     71 {
     72     int cnt = count();
     73     if(cnt == r) return m; // 不变部分为空
     74 
     75     int c = 0;
     76     for(int i = 0; i < b; i++)
     77         if(x[i] == m) 
     78             c++; // 可变部分第一行中有k种涂法的格子数
     79     m++; // 多了一行(可变部分的第一行)
     80     cnt = mul_mod(cnt, pow_mod(k, c));
     81     cnt = mul_mod(cnt, pow_mod(k-1, n - c));
     82     if(cnt == r) return m; // 此时cnt为不变部分和可变部分第一行的方案总数
     83 
     84     return log_mod(pow_mod(k-1,n), mul_mod(r, inv(cnt))) + m;
     85 }
     86 
     87 int main()
     88 {
     89     int T;
     90     scanf("%d", &T);
     91     for(int t = 1; t <= T; t++)
     92     {
     93         scanf("%d%d%d%d", &n, &k, &b, &r);
     94         bset.clear();
     95         m = 1;
     96         for(int i = 0; i < b; i++)
     97         {
     98             scanf("%d%d", &x[i], &y[i]);
     99             if(x[i] > m) m = x[i]; // 更新不变部分的行数
    100             bset.insert(make_pair(x[i], y[i]));
    101         }
    102         printf("Case %d: %d
    ", t, doit());
    103     }
    104 }
    View Code
  • 相关阅读:
    open-falcon之agent
    centos 7 部署 open-falcon 0.2.0
    高可用Redis服务架构分析与搭建
    python操作mongo脚本
    mongo查询日期格式数据
    离线下载pip包安装
    mongo同步到es
    mongo ttl索引
    kibana多台服务部署
    logstash过滤配置
  • 原文地址:https://www.cnblogs.com/ITUPC/p/4942255.html
Copyright © 2011-2022 走看看