因为题目要求同列相邻两格不同色,所以列与列之间不影响,可以逐列染色。

如果一个格子的上面相邻的格子,已经被染色则染这个格子的时候,共有k-1中选择。

反过来,如果一个格子位于第一列,或者上面相邻的格子是不能被染色的格子,则共有k中选择。

虽然,矩阵的行数不定,但至少为所有不能被染色格子行标的最大值m。

分别检验一下染m行和m+1行的方案数(mod 100000007)是否为r

否则的话,后面每染一行方案数都会乘p = (k-1)n,假设前面计算出来的m+1行方案数为cnt

下面的任务就是求解 px * cnt = r (mod MOD),两边乘cnt的逆,得 px = r * cnt-1 (mod MOD)

最后加上前面的m+1行,答案为x + m + 1

最后吐槽一下我认为的坑点=_=,看到那个模想当然地以为是1e9+7,但是最后一个样例调了好久没过,后来才发现题中给的模是1e8+7

 #include <cstdio>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
#define MP make_pair
#define INS insert
typedef long long LL; const int MOD = ;
const int maxb = + ;
int n, m, k, b, r, x[maxb], y[maxb], fir_row;
set<pair<int, int> > Set; int mul_mod(int a, int b)
{ return (LL) a * b % MOD; } int pow_mod(int a, LL n)
{
int ans = , base = a;
while(n)
{
if(n & ) ans = mul_mod(ans, base);
base = mul_mod(base, base);
n >>= ;
}
return ans;
} int inv(int a)
{ return pow_mod(a, MOD - ); } int log_mod(int a, int b)
{//a^x=b (mod MOD)
int m, v, e = , i;
m = (int)sqrt(MOD + 0.5);
v = inv(pow_mod(a, m));
map<int, int> x;
x[] = ;
for(i = ; i < m; i++)
{
e = mul_mod(e, a);
if(e == b) return i;
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 solve()
{
int c = ;//前m行涂k种颜色的格子个数
for(int i = ; i < b; i++)
if(x[i] != m && !Set.count(MP(x[i] + , y[i]))) c++;
c += n - fir_row;
int cnt = mul_mod(pow_mod(k, c), pow_mod(k-, (LL)m*n - b - c));
if(cnt == r) return m; c = ;//第m+1行涂k种颜色的格子个数
for(int i = ; i < b; i++) if(x[i] == m) c++;
cnt = mul_mod(mul_mod(cnt, pow_mod(k, c)), pow_mod(k-, n-c));
if(cnt == r) return m + ; int p = pow_mod(k-, n);
int v = inv(cnt);
return log_mod(p, mul_mod(r, v)) + m + ;
} int main()
{
//freopen("in.txt", "r", stdin); int T;
scanf("%d", &T);
for(int kase = ; kase <= T; kase++)
{
scanf("%d%d%d%d", &n, &k, &b, &r);
Set.clear();
m = ; fir_row = ;
for(int i = ; i < b; i++)
{
scanf("%d%d", &x[i], &y[i]);
Set.INS(MP(x[i], y[i]));
if(x[i] > m) m = x[i];
if(x[i] == ) fir_row++;//第一行不能被涂色的个数
}
printf("Case %d: %d\n", kase, solve());
} return ;
}

代码君

最新文章

  1. Windows下搭建Spark+Hadoop开发环境
  2. Flask备注4(Structure)
  3. Ini文件操作函数
  4. ListView真的蛮好用
  5. org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge]
  6. 【Windows 10 应用开发】自定义快捷键
  7. OCP 11G 实验环境安装文档 ( RedHat5.5 + Oracle11g )
  8. 同主机下Docker+nginx+tomcat负载均衡集群搭建
  9. Triangle (第8届山东省赛的某题)
  10. 让程序跳转到绝对地址0x100000去执行
  11. 【BZOJ4712】洪水
  12. 微信小程序 web-view 的 url 带参问题
  13. bzoj千题计划289:bzoj 2707: [SDOI2012]走迷宫
  14. 2018年全国多校算法寒假训练营练习比赛(第一场)C 六子冲
  15. hdu2080-2081
  16. mongo文本搜索的一个例子
  17. 修复损坏的 shapefile
  18. linux学习记录.2.hello world.c
  19. Log4j 汇总
  20. Golang的接口

热门文章

  1. android 开发,多个线程共用一个handler
  2. 原生JS实现苹果菜单
  3. HDU 5629 Clarke and tree dp+prufer序列
  4. Tern Server Timeout
  5. Leetcode#81 Search in Rotated Sorted Array II
  6. VS2010字体设置+推荐字体
  7. poj 2362
  8. Struts2 SSH整合框架返回json时,要注意懒加载问题
  9. lintcode:二叉树的中序遍历
  10. SqlDataAdapter用法