题意:用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. pthread_create用法

    linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread. #include <pthread.h> int pthread_create(pth ...

  2. BindingFlags说明

    为了获取返回值,必须指定 BindingFlags.Instance 或 BindingFlags.Static. 指定 BindingFlags.Public 可在搜索中包含公共成员. 指定 Bin ...

  3. HDU 1757 A Simple Math Problem(矩阵快速幂)

    题目链接 题意 :给你m和k, 让你求f(k)%m.如果k<10,f(k) = k,否则 f(k) = a0 * f(k-1) + a1 * f(k-2) + a2 * f(k-3) + …… ...

  4. 【转】奇异值分解(We Recommend a Singular Value Decomposition)

    文章转自:奇异值分解(We Recommend a Singular Value Decomposition) 文章写的浅显易懂,很有意思.但是没找到转载方式,所以复制了过来.一个是备忘,一个是分享给 ...

  5. cmd启动tomcat

    1.安装jdk 2.安装tomcat 3.需要配置两个用户环境变量,仅仅配置系统变量没用. a)JAVA_HOME:D:\programing~tools\java~tools\JDK(tm)\jdk ...

  6. Java面试题-并发容器和框架

    1. 如何让一段程序并发的执行,并最终汇总结果? 答:使用CyclicBarrier 和CountDownLatch都可以,使用CyclicBarrier 在多个关口处将多个线程执行结果汇总,Coun ...

  7. 通用权限管理系统Ver2.0

    通用权限管理系统Ver2.0平台采用kendo+mvc4+Nhibernate技术实现,底层采用自定义ORM实现数据库底层代码,支持Oracle.SqlServer.mysql等常用数据库,界面采用k ...

  8. 使用委托的BeginInvoke方法来完成复杂任务的操作

    现在假设我有这样一个窗体(包含一个进度条和一个按钮与两个文本框),在第一个文本框中输入一个数字进行阶乘运算,在此过程中进度条与运算进度保持一致,同时可以在第二个文本框中进行其它工作(比如输入).对付这 ...

  9. HTTP编程(六)

    此为网络编程的一个系列,后续会把内容补上.....

  10. Java [Leetcode 217]Contains Duplicate

    题目描述: Given an array of integers, find if the array contains any duplicates. Your function should re ...