Uva_11916 Emoogle Grid

题目链接

题意:

  有个N X M的棋盘, 有K种颜色, 有B个不可涂色的位置, 共有R种涂色方案。

  1)每个可涂色的位置必须涂上一种颜色

  2)不可涂色位置不能涂色

  3)每个位置必须从K种颜色中选出一种颜色进行涂色

  4)当前格子(x,y) 上面的那个格子(x+1,y)不能同色

  

  现在已知N, K, B, R, 求满足条件的最小的M

  

思路:

  B个不可涂色位置设为(x1, y1), (x2, y2), (x3, y3), ... , (xb, yb)

  1)M必然 ≥ max(x[i])

  2)设前max(x[i]) 行 与 max(x[i]) + 1 行涂色方案为 cnt, 则 max(x[i]) + 1之后的每一行, 涂色方案都是 (K-1)^N。

  3)设P = (K - 1) ^ N

  存在一个j 使得:

          cnt * P^j = R

  右乘cnt的逆元 cnt ^ -1 得:

          P^j = R * cnt ^ -1

  即求一个最小的j满足上式。

          P^j ≡ R * cnt ^ -1 (mod MOD) , MOD = 100000007

  利用对数取余进行求解

  

  代码如下:

  

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <ctime>
  6 #include <set>
  7 #include <map>
  8 #include <list>
  9 #include <queue>
 10 #include <string>
 11 #include <vector>
 12 #include <fstream>
 13 #include <iterator>
 14 #include <iostream>
 15 using namespace std;
 16 #define LL long long
 17 #define MAXN 550
 18 #define MOD 100000007
 19 int n, b, r, k, m;
 20 int x[MAXN], y[MAXN];
 21 set<pair<int, int> > best;
 22
 23 void ex_gcd(LL a, LL b, LL& d, LL& x, LL& y)
 24 {
 25     if(!b) {d = a; x = 1; y = 0;}
 26     else
 27     {ex_gcd(b, a%b, d, y, x); y -= x*(a/b);}
 28 }
 29
 30 LL inv(LL a)
 31 {
 32     LL d, x, y;
 33     ex_gcd(a, MOD, d, x, y);
 34     return d == 1?(x + MOD) % MOD : -1;
 35 }
 36
 37 LL mul_mod(LL a, LL b)
 38 {
 39     return a * b % MOD;
 40 }
 41
 42 LL pow_mod(LL a, LL p)
 43 {
 44     if(p == 0) return 1;
 45     LL ans = pow_mod(a, p/2);
 46     ans = ans * ans % MOD;
 47     if(p % 2 == 1) ans = ans * a % MOD;
 48     return ans;
 49 }
 50
 51 int log_mod(int a, int b)
 52 {
 53     int m, v, e = 1, i;
 54     m = (int)sqrt(MOD+0.5);
 55     v = inv(pow_mod(a, m));
 56     map<int, int> x;
 57     x[1] = 0;
 58     for (int i = 1; i < m; i++)
 59     {
 60         e = mul_mod(e, a);
 61         if (!x.count(e))
 62             x[e] = i;
 63     }
 64     for (int i = 0; i < m; i++)
 65     {
 66         if (x.count(b))
 67             return i*m + x[b];
 68         b = mul_mod(b, v);
 69     }
 70     return -1;
 71 }
 72
 73 int solve()
 74 {
 75     int cur = 0;
 76     int cnt = 0;
 77
 78     for(int i = 0; i < b; i ++)
 79         if(x[i] != m && !best.count(make_pair(x[i] + 1, y[i]))) cur ++;
 80     cur += n;
 81     for(int i = 0; i < b; i ++)
 82         if(x[i] == 1) cur --;
 83
 84     // ans = k^cur * (k-1) ^ (n*m - b - cur);
 85     cnt = mul_mod(pow_mod(k, cur), pow_mod(k - 1, (LL)n * m - b - cur));
 86
 87     if(cnt == r) return m;
 88
 89     cur = 0;
 90     for(int i = 0; i < b; i ++)
 91         if(x[i] == m) cur ++;
 92
 93     //ans = cnt * k^cur * (k - 1)^(n - cur);
 94     cnt = mul_mod(cnt, pow_mod(k, cur));
 95     cnt = mul_mod(cnt, pow_mod(k - 1, n - cur));
 96     m ++;
 97
 98     if(cnt == r) return m;
 99
100     //printf("%d %d %d\n", pow_mod(k - 1, n), inv(cnt), log_mod(pow_mod(k - 1, n), mul_mod(r, inv(cnt))));
101     // P = (k - 1) ^ n,  P^x = r * cnt^-1;
102     return log_mod(pow_mod(k - 1, n), mul_mod(r, inv(cnt))) + m;
103 }
104
105 int main()
106 {
107     int T;
108     scanf("%d", &T);
109     for(int kcase = 1; kcase <= T; kcase ++)
110     {
111         scanf("%d %d %d %d", &n, &k, &b, &r);
112         best.clear();
113         m = 1;
114         for(int i = 0; i < b; i ++)
115         {
116             scanf("%d %d",&x[i], & y[i]);
117             m = max(m, x[i]);
118             best.insert(make_pair(x[i], y[i]));
119         }
120         printf("Case %d: %d\n", kcase, solve());
121     }
122     return 0;
123 }

  这题WA了一天, 反复找错都没找到, 重写第N + 1次的时候终于找到错误 , 求逆函数写错了 囧

时间: 2024-10-20 11:58:49

Uva_11916 Emoogle Grid的相关文章

[uva11916] Emoogle Grid (离散对数)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud  Emoogle Grid  You have to color an MxN ( 1M, N108) two dimensional grid. You will be provided K ( 2K108) different colors to do so. You will also be provided a list of B ( 0B500) list of blo

UVA 11916 - Emoogle Grid(数论)

UVA 11916 - Emoogle Grid 题目链接 题意:一个N列的网格,有B个格子可以不涂色,其他格子各涂一种颜色,现在一共有k种颜色,要求同一列格子颜色不能相同,问总方案数 MOD 100000007答案等于R时最小的M是多少. 思路:先把格子分为两部分,有不涂色的一部分,没有的一部分,然后计算出有的情况数,之后如果每多一行,每个格子上能涂颜色必然是k - 1种,也就是每多一行多(k - 1)^n总方案,所以也就是求 前一部分情况 * ((k - 1)^n)^x % MOD = R时

uva 11916 - Emoogle Grid(大步小步算法)

题目连接:uva 11916 - Emoogle Grid 题目大意:有一问题,在M行N列的网格上涂K种颜色,其中有B个格子不用涂色,其它每个格子涂一种颜色,同一列的上下两个相邻的格子不能涂相同的颜色.给出M,N,K和B个格子的位置,求出总方案数模掉1e8+7的结果R.现在已知R,求最小的M. 解题思路:有确定不用涂色格子的区域作为不变部分,总数通过计算为tmp,外加可变部分的第一行,方案数为cnt,可变部分除第一行外,每加一行都将总数乘以(K?1)N,既有 cnt?PM=Rmod(1e8+7)

UVA - 11916 Emoogle Grid (离散对数取模)

You have to color an M x N (1M, N108) two dimensional grid. You will be provided K (2K108) different colors to do so. You will also be provided a list of B (0B500)list of blocked cells of this grid. You cannot color those blocked cells. A cell can be

UVA 11916 Emoogle Grid 离散对数 大步小步算法

LRJ白书上的题 #include <stdio.h> #include <iostream> #include <vector> #include <math.h> #include <set> #include <map> #include <queue> #include <algorithm> #include <string.h> #include <string> using

UVa 11916 (离散对数) Emoogle Grid

因为题目要求同列相邻两格不同色,所以列与列之间不影响,可以逐列染色. 如果一个格子的上面相邻的格子,已经被染色则染这个格子的时候,共有k-1中选择. 反过来,如果一个格子位于第一列,或者上面相邻的格子是不能被染色的格子,则共有k中选择. 虽然,矩阵的行数不定,但至少为所有不能被染色格子行标的最大值m. 分别检验一下染m行和m+1行的方案数(mod 100000007)是否为r 否则的话,后面每染一行方案数都会乘p = (k-1)n,假设前面计算出来的m+1行方案数为cnt 下面的任务就是求解 p

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行

uva11916 Emoogle Grid (BSGS)

https://uva.onlinejudge.org/external/119/p11916.pdf 令m表示不能染色的格子的最大行号 设>m行时可以染k种颜色的格子数有ck个,恰好有m行时可以染k种颜色的格子数有ckm个 分m行.m+1行.>m+1行讨论 如果是m行:k^ckm * (k-1)^(n*m-b-ckm) = r 如果是m+1行, k^ckm * (k-1)^(n*m-b-ckm) * k^(ck-ckm) * (k-1)^(n-(ck-ckm)) = r 如果>m行,k

UVA - 11916 Emoogle Grid (组合计数+离散对数)

假如有这样一道题目:要给一个M行N列的网格涂上K种颜色,其中有B个格子不用涂色,其他每个格子涂一种颜色,同一列中的上下两个相邻格子不能涂相同颜色.给出M,N,K和B个格子的位置,求出涂色方案总数除以1e8+7的结果R. 本题的任务和这个相反:已知N,K,R和B个格子的位置,求最小可能的M. 蓝书(大白)上的例题,设xm为不能涂色的格子的最大x值,则分三种情况讨论:M=xm,M=xm+1,M>xm+1.前两种用组合公式直接算,第三种可设前xm+1行的格子涂色方法有n种,由于每增加一行,总涂色方案数