题意:用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)。

 #include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
using namespace std; const int MOD = ;
const int maxb = + ;
int n, m, k, b, r, x[maxb], y[maxb];
set<pair<int, int> > bset; int pow_mod(int a, long long p)
{
if(p == )
return ;
int ans = pow_mod(a, p/);
ans = (long long)ans * ans % MOD;
if(p%)
ans = (long long)ans * a % MOD;
return ans;
} int mul_mod(int a, int b)
{
return (long long)a * b % MOD;
} int inv(int a)
{
return pow_mod(a, MOD-);
} int log_mod(int a, int b)
{
int m, v, e = , i;
m = (int)sqrt(MOD);
v = inv(pow_mod(a, m));
map <int,int> x;
x[] = ;
for(i = ; i < m; i++)
{
e = mul_mod(e, a);
if (!x.count(e)) x[e] = i;
}
for(i = ; i < m; i++)
{
if(x.count(b)) return i*m + x[b];
b = mul_mod(b, v);
}
return -;
} // 计算可变部分的方案数
int count()
{
int c = ; // 有k种涂法的格子数
for(int i = ; i < b; i++)
{
if(x[i] != m && !bset.count(make_pair(x[i]+, y[i]))) c++; // 不可涂色格下面的可涂色格
}
c += n; // 第一行所有空格都有k种涂法
for(int i = ; i < b; i++)
if(x[i] == ) c--; // 扣除那些不能涂色的格子 // ans = k^c * (k-1)^(mn - b - c)
return mul_mod(pow_mod(k, c), pow_mod(k-, (long long)m*n - b - c));
} int doit()
{
int cnt = count();
if(cnt == r) return m; // 不变部分为空 int c = ;
for(int i = ; i < b; i++)
if(x[i] == m)
c++; // 可变部分第一行中有k种涂法的格子数
m++; // 多了一行(可变部分的第一行)
cnt = mul_mod(cnt, pow_mod(k, c));
cnt = mul_mod(cnt, pow_mod(k-, n - c));
if(cnt == r) return m; // 此时cnt为不变部分和可变部分第一行的方案总数 return log_mod(pow_mod(k-,n), mul_mod(r, inv(cnt))) + m;
} int main()
{
int T;
scanf("%d", &T);
for(int t = ; t <= T; t++)
{
scanf("%d%d%d%d", &n, &k, &b, &r);
bset.clear();
m = ;
for(int i = ; i < b; i++)
{
scanf("%d%d", &x[i], &y[i]);
if(x[i] > m) m = x[i]; // 更新不变部分的行数
bset.insert(make_pair(x[i], y[i]));
}
printf("Case %d: %d\n", t, doit());
}
}

uva 11916 Emoogle Grid的更多相关文章

  1. uva 11916 Emoogle Grid (BSGS)

    UVA 11916 BSGS的一道简单题,不过中间卡了一下没有及时取模,其他这里的100000007是素数,所以不用加上拓展就能做了. 代码如下: #include <cstdio> #i ...

  2. UVA 11916 Emoogle Grid(同余模)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

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

    LRJ白书上的题 #include <stdio.h> #include <iostream> #include <vector> #include <mat ...

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

    假如有这样一道题目:要给一个M行N列的网格涂上K种颜色,其中有B个格子不用涂色,其他每个格子涂一种颜色,同一列中的上下两个相邻格子不能涂相同颜色.给出M,N,K和B个格子的位置,求出涂色方案总数除以1 ...

  5. [uva11916] Emoogle Grid (离散对数)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud  Emoogle Grid  You have to color an MxN ( ...

  6. uva 11916 解模方程a^x=b (mod n)

      Emoogle Grid  You have to color an M x N ( 1M, N108) two dimensional grid. You will be provided K  ...

  7. UVA11916 Emoogle Grid

    Emoogle Grid You have to color an M × N (1 ≤ M, N ≤ 108 ) two dimensional grid. You will be provided ...

  8. UVa 11916 (离散对数) Emoogle Grid

    因为题目要求同列相邻两格不同色,所以列与列之间不影响,可以逐列染色. 如果一个格子的上面相邻的格子,已经被染色则染这个格子的时候,共有k-1中选择. 反过来,如果一个格子位于第一列,或者上面相邻的格子 ...

  9. uva11916 Emoogle Grid (BSGS)

    https://uva.onlinejudge.org/external/119/p11916.pdf 令m表示不能染色的格子的最大行号 设>m行时可以染k种颜色的格子数有ck个,恰好有m行时可 ...

随机推荐

  1. C#学习笔记(三)

    1.我们在Main()函数中,调用Test()函数,我们管Main()函数称之为调用者,管Test()函数称之为被调用者.如果被调用者想要得到调用者的值:1).传递参数.2).使用静态字段来模拟全局变 ...

  2. 配置JAVA的环境变量

    下面开始配置环境变量,右击[我的电脑]---[属性]-----[高级]---[环境变量],如图: 选择[新建系统变量]--弹出“新建系统变量”对话框,在“变量名”文本框输入“JAVA_HOME”,在“ ...

  3. python top project of 2013

    Hi Pythonistas! 测试和调试 Testing & Debugging 框架及Web Frameworks & Web 并发 Concurrency 任务调度 Job Sc ...

  4. How to Cope with Deadlocks

    http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html How to Cope with Deadlocks This section ...

  5. POJ2187Beauty Contest

    http://poj.org/problem?id=2187 题意 :有一个农场有N个房子,问最远的房子相距多少距离 . 思路 :凸包,旋转卡壳,通过寻找所有的对锺点,找出最远的点对. #includ ...

  6. codeforces #313 div1 E

    首先我们要注意到一个事情 如果一个灯塔向左覆盖,那么比他小的某个灯塔如果向左覆盖的端点大于当前塔向左覆盖的端点,他一定向右覆盖 对于当前灯塔向右覆盖也是同理 那么我们只需要记录当前覆盖到的端点就可以完 ...

  7. RedMine项目管理系统邮件推送设置(Windows环境)

    RedMine项目管理系统有邮箱推送功能,当Bug,安全漏洞等内容被修改.解决.评论的时候,系统会通过邮件 及时的通知你的团队和客户.邮件通知的环节.形式.时间.接受人均可定制,功能十分实用. 下面是 ...

  8. ios 应用剖析

    在创建HelloWorld的过程中,生成了很多文件(展开Xcode左边的项目导航视图可以看到,如图2-8所示),它们各自的作用是什么?彼此间又是怎样的一种关系呢? 图2-8 项目导航视图 如图2-8所 ...

  9. JavaScript DOM高级程序设计 2.4-try{}catch{}--我要坚持到底!

    先看一段有异常的语句 var sound = 'Roar!'; function myOrneryBeast() { this.style.color='green';//window没有style属 ...

  10. 【HDOJ】3948 The Number of Palindromes

    后缀数组求不重复回文子串数目.注意dp数组. /* 3948 */ #include <iostream> #include <sstream> #include <st ...