其实思维难度不是很大,但是各种处理很麻烦,公式推导到最后就是一个bsgs算法解方程

/*
要给M行N列的网格染色,其中有B个不用染色,其他每个格子涂一种颜色,同一列上下两个格子不能染相同的颜色
涂色方案%100000007的结果是R,现在给出R,N,K,请求出最小的M
对于第一行来说,每个位置有k种选择,那么填色方案数是k^n
对于第二行来说,每个位置有k-1中选择,那么填色方案数时(k-1)^n种
依次类推,如果i+1行的某个格子上面是白格,那么这个格子有k种填色方案 将M行分为两部分,第一部分是固定的,即行数最大的B向下一行,注意特判情况
第二部分是不固定的,即不停增加行数M,直到求出结果=R 另P=(K-1)^N,所以方案总数是cnt*P^M=R (mod 100000007)
P^M = cnt^-1 * R(mod 100000007)
逆元算一下即可
用bsgs算法 解出这个关于M的方程即可
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 510
#define mod 100000007 int n,m,k,b,r,x[maxn],y[maxn];
set<pair<int,int> >best; ll pow_mod(ll a,ll p){//快速幂
ll res=;
while(p){
if(p%)
res=res*a%mod;
p>>=;
a=a*a%mod;
}
return res;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
if(b==){x=;y=;return a;}
ll d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
ll inv(ll a){//ax+y*mod=1 ==> ax=1(mod mod),所以x就是a关于mod的逆元
ll d,x,y;
d=exgcd(a,mod,x,y);
return d==?(x+mod)%mod:-;
}
int log_mod(int a,int b){//bsgs算法,求解a^x=b(mod m)方程
int m, v, e = , i;
m = (int)sqrt(mod+0.5);
v = inv(pow_mod(a, m));
map<int, int> x;
x[] = ; for(int j=;j<m;j++){//建立hash表,x=i*m+j
e=(ll)e*a%mod;
if(!x.count(e))
x[e]=j;
}
for(int i=;i<m;i++){
if(x.count(b))
return i*m+x[b];
b=(ll)b*v%mod;//这里实际上是用逆元处理了,即将a^(i*m+j)=b (mod m)转化为a^j=b^(i*m)^(-1) (mod m)
}
return -;
}
int count(){//计算固定部分的方案数
int c=;//统计b块下面的的方格
for(int i=;i<b;i++)
if(x[i]!=m && !best.count(make_pair(x[i]+,y[i])))
c++;
c+=n;
for(int i=;i<b;i++)
if(x[i]==)
c--; return pow_mod(k-,(ll)m*n-b-c)*pow_mod(k,c)%mod;
}
int doit(){
int cnt=count();//先求出第一部分的cnt
if(cnt==r)
return m; int c=;//要把第m+1行单独拿出来考虑
for(int i=;i<b;i++)
if(x[i]==m)
c++;
m++;
cnt=cnt*pow_mod(k,c)%mod;
cnt=cnt*pow_mod(k-,n-c)%mod;
if(cnt==r)
return m; //接下去就只要求对数方程即可
int P=pow_mod(k-,n);
return log_mod(P,r*inv(cnt)%mod)+m;
}
int main(){
int t,cas=;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d",&n,&k,&b,&r);
best.clear();
m=;
for(int i=;i<b;i++){
scanf("%d%d",&x[i],&y[i]);
m=max(x[i],m);
best.insert(make_pair(x[i],y[i]));
}
printf("Case %d: %d\n",cas++,doit());
}
}

uva11916 bsgs算法逆元模板,求逆元,组合计数的更多相关文章

  1. 公钥密码之RSA密码算法扩展欧几里德求逆元!!

    扩展欧几里得求逆元 实话说这个算法如果手推的话问题不大,无非就是辗转相除法的逆过程,还有一种就是利用扩展欧几里德算法,学信安数学基础的时候问题不大,但现在几乎都忘了,刷题的时候也是用kuangbin博 ...

  2. BSGS算法(模板)

    BSGS (大步小步算法) 已知\(a.b. c\),求\(x\).令\(a^x \equiv b \pmod c\). 步骤 \[m = \lceil \sqrtc\ \rceil \]\[x = ...

  3. 算法竞赛进阶指南0x36组合计数

    概述 AcWing211. 计算系数 #include <bits/stdc++.h> using namespace std; const int mod = 10007 ; int k ...

  4. hdu 1576 求逆元

    题意:给出n=A mod 9973和B,求(A/B) mod 9973 昨天用扩展欧几里得做过这题,其实用逆元也可以做. 逆元的定义:例如a*b≡1 (mod m),则b就是a关于m的逆元. 求逆元方 ...

  5. POJ2417 Discrete Logging | A,C互质的bsgs算法

    题目: 给出A,B,C 求最小的x使得Ax=B  (mod C) 题解: bsgs算法的模板题 bsgs 全称:Baby-step giant-step 把这种问题的规模降低到了sqrt(n)级别 首 ...

  6. Codeforces 451E Devu and Flowers(组合计数)

    题目地址 在WFU(不是大学简称)第二次比赛中做到了这道题.高中阶段参加过数竞的同学手算这样的题简直不能更轻松,只是套一个容斥原理公式就可以.而其实这个过程放到编程语言中来实现也没有那么的复杂,不过为 ...

  7. 多项式求逆元详解+模板 【洛谷P4238】多项式求逆

    概述 多项式求逆元是一个非常重要的知识点,许多多项式操作都需要用到该算法,包括多项式取模,除法,开跟,求ln,求exp,快速幂.用快速傅里叶变换和倍增法可以在$O(n log n)$的时间复杂度下求出 ...

  8. BSGS算法+逆元 POJ 2417 Discrete Logging

    POJ 2417 Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4860   Accept ...

  9. 线性筛prime/phi/miu/求逆元模板

    这绿题贼水...... 原理我不讲了,随便拿张草稿纸推一下就明白了. #include <cstdio> using namespace std; ; int su[N],ans,top; ...

随机推荐

  1. Web三层-UI/BLL/DAL/MODEL

    2013传智播客视频\视频\2013-05-28-EF\视频 创建4个程序集,添加引用,model添加映射, P01UI表现层--BLL+MODELP02BLL业务层--DAL+MODELP03DAL ...

  2. 前端-----html(1)

    基本结构 Doctype Doctype告诉浏览器使用什么样的html或xhtml规范来解析html文档 <!DOCTYPE html> bead标签 Meta 提供有关页面的元信息,例: ...

  3. 在Linux环境下使用Apache部署ASP.NET Core

    在前几篇文章中我们一起探讨了如何在Linux环境中安装ASP.NET Core运行时环境及将ASP.NET Core项目部署在Jexus中,这篇文章中我们将探讨如何将ASP.NET Core部署于Ap ...

  4. delphi 的插件机制与自动更新

    delphi 的插件机制与自动更新 : 1.https://download.csdn.net/download/cxp_2008/2226978   参考 2.https://download.cs ...

  5. 二层环路保护,RRPP多环的配置

    作者:邓聪聪 组网需求: 局域网中,由A/B/C/D构成RRPP域1换网络结构,要求环网机构中的任意两条线路中断都不能影响业务. 配置思路: 环路由两部分组成,ring1.ring2,B为环1的主节点 ...

  6. 使用cstdiofile在vs2010中无法写入中文的问题

    在VC2010环境下, 以下代码无法实现使用CStdioFile向文本文件中写入中文(用notepad.exe查看不到写入的中文) CStdioFile file; file.Open(…); fil ...

  7. boost.python入门教程 ----python 嵌入c++

    Python语言简介 Python是一种脚本语言.以开放的开发接口和独特的语法著称.尽管Python在国内引起注意只有几年的时间,但实际上Python出现于上世纪90年代(据www.python.or ...

  8. ifconfig相关参数及用法说明

    一.ifconfig ifconfig 主要是可以手动启动.观察与修改网络接口的相关参数,可以修改的参数很多,包括 IP 参数以及 MTU 等都可以修改,它的语法如下: [root@linux ~]# ...

  9. 解决:fatal error LNK1104: 无法打开文件“libc.lib”

    今天使用VS2017编译比较老的VC++项目,出现了[fatal error LNK1104: 无法打开文件“libc.lib”]的链接器问题,解决方法如下: 项目->属性中->配置属性- ...

  10. ansible笔记(11):初识ansible playbook(二)

    ansible笔记():初识ansible playbook(二) 有前文作为基础,如下示例是非常容易理解的: --- - hosts: test211 remote_user: root tasks ...