【zoj3254】Secret Code
题意:
给出a、p、d、m 求a^x=d(mod p) 0<=x<=m 的解的个数
题解:
今天一整天的时间大部分都在调这题Orz BSGS什么的还是太不熟了
我们可以用BSGS拓展版求出最小解x 以及循环节开始的位置start start就是p被除(a,p)的次数
如果不存在解x 或x>m则输出0
如果x<start 那么输出1 因为如果解在循环节之前 在循环节中就不可能有x的解
如果start<=x<=m 答案就是x循环出现的次数=(m-x)/lon (lon是循环节长度)
这有些地方要注意的
因为题目的m<=2^63-1 而0<=x<=m 所以可能导致答案爆long long 要开unsigned long long
还有该mod的地方要mod啊 因为一个mod 我段异常了一个早上
然后因为对BSGS不熟 WA了一下午TAT 按AK大神的打法重打一遍才过
代码:

#include <cstdio>
#include <cstring>
#include <cmath>
typedef long long ll;
typedef unsigned long long ull;
const ll mo=,N=;
ll a,p,d,m,sum=,sq,hash[mo],hat[mo],pri[N],save[N],bo[N+],tot,add;
ll gcd(ll a,ll b){ return b ? gcd(b,a%b) : a; }
ll extgcd(ll &x,ll &y,ll a,ll b){
if (!b){
x=,y=;
return a;
}else{
ll res=extgcd(x,y,b,a%b),t=x;
x=y,y=t-a/b*y;
return res;
}
}
void push(ll x,ll y){
ll t=x%mo;
while (hash[t]>=){
if (hash[t]==x) return;
t=(t+)%mo;
}
hash[t]=x,hat[t]=y;
}
void makehash(){
for (ll i=,x=%p;i<sq;i++,x=x*a%p) push(x,i);
}
ll ha(ll x){
ll t=x%mo;
while (hash[t]>=){
if (hash[t]==x) return hat[t];
t=(t+)%mo;
}
return -;
}
ll mi(ll a,ll b){
ll res=;
for (;b;b>>=){
if (b&) res=res*a%p;
a=a*a%p;
}
return res;
}
ll makex(){
ll x,y,a1,b1=p,res;
for (ll i=;i<=sq;i++){
a1=mi(a,sq*i)*sum%p;
ll gc=extgcd(x,y,a1,b1),xx=b1/gc;
if (d%gc) continue;
x=(d/gc*x%xx+xx)%xx;
res=ha(x);
if (res>= && res<=p)
return i*sq+res+add;
}
return -;
}
void makepri(){
for (ll i=;i<=N;i++){
if (!bo[i]) pri[++pri[]]=i;
for (ll j=;j<=pri[] && i*pri[j]<=N;j++){
bo[i*pri[j]]=;
if (!(i%pri[j])) break;
}
}
}
bool check(ll t){ return mi(a,t)==; }
void makesave(ll x){
save[]=;
for (ll i=;i<=pri[] && x>;++i)
if (!(x%pri[i])){
save[++save[]]=pri[i];
while (!(x%pri[i])) x/=pri[i];
}
if (x>) save[++save[]]=x;
}
ll phi(ll t){
makesave(t);
ll res=t;
for (ll i=;i<=save[];i++)
res=res/save[i]*(save[i]-);
return res;
}
ll makelon(){
ll t=phi(p);
makesave(t);
for (ll i=;i<=save[];i++)
while (check(t/save[i]) && !(t%save[i])) t/=save[i];
return t;
}
int bsgs(){
int addx=,sd=d,sp=p;
for (int gc=gcd(a,p);gc>;gc=gcd(a,p)){
if (addx==sd) return add++;
if (d%gc) return -;
addx=addx*a%sp;
d/=gc,p/=gc;
sum=a/gc*sum%p;
++add;
}
sq=(ll)sqrt(p);
a%=p;
makehash();
return makex();
}
void work(){
ull res=;
add=,sum=;
memset(hash,-,sizeof(hash));
ll x=bsgs();
if (x==- || x>m){
puts("");
return ;
}else if (x<add){
puts("");
return;
}
ll lon=makelon();
res=(m-x)/lon+;
printf("%I64u\n",res);
}
int main(){
makepri();
while (scanf("%I64d%I64d%I64d%I64d",&a,&p,&d,&m)!=EOF){
++tot;
//printf("%d:",tot);
a%=p;
work();
}
}
【zoj3254】Secret Code的更多相关文章
- 【Trie】Secret Message 秘密信息
[题目链接]: https://loj.ac/problem/10054 [题意] 我认为这个题目最难的是题意: 其实分了两种情况: 1.如果当前文本串匹配不完,那么答案的是:匹配过程中遇到的模式串结 ...
- 【记录】EF Code First 实体关联,如何添加、修改实体?
在使用 EF Code First 的时候,我们经常会对项目中的 Entry 进行一对多.多对多的映射配置,这时候就会产生主实体和子实体的概念,我们在添加.修改他们的时候,有时候会产生一些问题,比如添 ...
- 【LeetCode】Gray Code
Gray Code The gray code is a binary numeral system where two successive values differ in only one bi ...
- 【leetcode】Gray Code (middle)
The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...
- 【题解】【排列组合】【回溯】【Leetcode】Gray Code
The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...
- 【Idea】idea code style配置eclipse code formatter
在eclipse中有自动配置code style的功能 ,但是idea上却没有,这个时候需要自己手工配置 1. 在idea中找到Preference->Plugins->Browse re ...
- 【转】PowerDesigner code、name显示设置 及 同时显示办法
原文地址:http://blog.csdn.net/fy_hanxu/article/details/52468927 菜单->Tool->Model Options->Name C ...
- 【EF】EF Code First Migrations数据库迁移
1.EF Code First创建数据库 新建控制台应用程序Portal,通过程序包管理器控制台添加EntityFramework. 在程序包管理器控制台中执行以下语句,安装EntityFramewo ...
- 【Leetcode】【Medium】Gray Code
The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...
随机推荐
- case class inheritance
Scala 禁止case class inheritance case class Person(name: String, age: Int) case class FootballPlayer(n ...
- hdu 3389 Game 博弈论
思路: 其本质为阶梯博弈; 阶梯博弈:博弈在一列阶梯上进行,每个阶梯上放着自然数个点,两个人进行阶梯博弈... 每一步则是将一个集体上的若干个点( >=1 )移到前面去,最后没有点可以移 ...
- 2013 Multi-University Training Contest 4 Who's Aunt Zhang
看题就知道要用polya,但是当时没做出来,还是不是很熟悉polya!!! 总共有24种置换: 1. 不做任何旋转 K ^ (54 + 12 + 8) 2. 绕相对面中心的轴转 1) 90度 K ^ ...
- Android 文字链接 文字点击时的背景颜色
案例:实现“忘记密码?”这个链接,并且在按下的时候改变颜色. 方法一:这个可以用TextView实现: 主界面main.xml: <?xml version="1.0" en ...
- hibernate 字段名最好不要使用数据库的保留字
请看如下红色部分,show为mysql的保留字,所以我在hibernate修改show字段值的时候出现错误,原来是show跟mysql的保留字相同了 CREATE TABLE `t_letter` ( ...
- Qt: 访问容器(三种方法,加上for循环就四种了)good
#include <iostream>#include <QString>#include <QList>#include <QListIterator> ...
- 编程实现Windows关机、重启、注销
要想编程使Windows关机.重启或者注销,可以使用ExWindowsEx这个API函数,该函数只有两个参数,第一个表示关机动作的标志,也就是你要让该函数关机呢,还是重启,还是注销等.可以使用EWX_ ...
- (转)linux 技巧:使用 screen 管理你的远程会话
转自:http://www.ibm.com/developerworks/cn/linux/l-cn-screen/index.html 你是不是经常需要 SSH 或者 telent 远程登录到 Li ...
- window的cmd窗口运行git
般情况下,我们在 Window 下安装好 git 后,在运行里面打开 cmd 窗口,在里面直接运行 git --version ,会提示“不是内部或外部命令,也不是一个可运行的程序”. 要想在cmd窗 ...
- Mysql DBA 20天速成教程,DBA大纲
Mysql DBA 20天速成教程 基本知识1.mysql的编译安装2.mysql 第3方存储引擎安装配置方法3.mysql 主流存储引擎(MyISAM/innodb/MEMORY)的特点4.字符串编 ...