A^x = D (mod P)

0 <= x <= M, here M is a given integer.

1 <= A, P < 2^31, 0 <= D < P, 1 <= M < 2^63

----------------------------------------------------------

裸拓展baby step giant step

先转成非拓展版,然后如果在转的过程中就出解了,则return 1,否则就找出=D的起点和循环节长度,然后直接求解。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
const int Hash_MOD = 1000003;
typedef long long LL;
typedef unsigned long long ULL;
LL times;
struct link
{
LL link;
int val,next;
}es[100000];
struct triple
{
LL x,y,g;
triple(const LL _x = 0,const LL _y = 0,const LL _g = 0):
x(_x),y(_y),g(_g){}
};
int H[Hash_MOD * 2],ec;
triple exgcd(const LL a,const LL b)
{
if (!b) return triple(1,0,a);
const triple last(exgcd(b,a%b));
return triple(last.y,last.x - a / b * last.y,last.g);
}
LL rem_equ(const LL a,const LL b,const LL c)
{
//ax == c (mod b)
//ax mod b == c
const triple tmp(exgcd(a,b));
const LL MOD = (b / tmp.g);
return ((tmp.x * (c / tmp.g) % MOD) + MOD) % MOD;
}
LL find(const LL x)
{
for (int i = H[x%Hash_MOD]; i; i = es[i].next)
if (es[i].link == x) return es[i].val;
return -1;
}
void insert(LL x,const LL v)
{
if (find(x) != -1) return;
const LL key = x % Hash_MOD;
es[++ec].next = H[key];
H[key] = ec;
es[ec].link = x;
es[ec].val = v;
}
LL BSGS(LL A,LL P,LL D)
{
LL AA = 1 % P,x = 1 % P,MOD = P,DD = D,m = static_cast<LL>(std::ceil(std::sqrt((double)P)));
times = 0;
for (triple tmp; (tmp = exgcd(A,P)).g != 1; ) {
if (x == DD) return times++;
if (D % tmp.g) return -1;
P /= tmp.g;
D /= tmp.g;
(AA *= A / tmp.g) %= P;
++times;
(x *= A) %= MOD;
}
A %= P;
ec = 0;
memset(H,0,sizeof H);
LL tmp = 1 % P;
for (int i = 0; i < m; ++i,(tmp *= A) %= P)
insert(tmp,i);
x = 1 % P;
for (LL i = 0; i < m; ++i,(x *= tmp) %= P) {
const int j = find(rem_equ(AA*x%P,P,D));
if (j != -1) return i * m + j + times;
}
return -1;
}
LL getphi(LL x)
{
LL res = 1;
for (LL i = 2; i * i <= x; ++i)
if (x % i == 0) {
x /= i;
res *= i - 1;
while (x % i == 0) x /= i,res *= i;
}
if (x > 1) res *= x - 1;
return res;
}
LL power(LL a,LL k,LL MOD)
{
//a ^ k % MOD
LL res = 1 % MOD;
for (; k; k/=2,(a *= a) %= MOD)
if (k & 1) (res *= a) %= MOD;
return res;
}
LL calc_len(const LL start,const LL A,const LL P,const LL D)
{
//A ^ (start + *this) == A ^ start == D (mod P)
LL phi = getphi(P),res = phi;
for (LL i = 2; i * i <= phi; ++i) {
for (; phi % i == 0; phi /= i);
for (; res % i == 0 && power(A,start + res/i,P) == D; res /= i);
}
if (phi > 1)
for (; res % phi == 0 && power(A,start + res/phi,P) == D; res /= phi);
return res;
}
ULL work(const LL A,const LL P,const LL D,const ULL M)
{
LL start = BSGS(A,P,D);
//printf("%lld\n",start);
if (start == -1 || start > M) return 0;
else if (start < times) return 1;
// LL phi=getphi(P);
// if (power(A,start + phi,P) != D) return 1;
ULL len = calc_len(start,A,P,D);
return (M - start) / len + 1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("3254.in","r",stdin);
freopen("3254.out","w",stdout);
#endif
LL A,P,D;
ULL M;
while (~scanf("%lld%lld%lld%llu",&A,&P,&D,&M))
printf("%llu\n",work(A%P,P,D,M));
}

[ZOJ3254] MON 9.2009Secret Code的更多相关文章

  1. 【zoj3254】Secret Code

    题意: 给出a.p.d.m 求a^x=d(mod p) 0<=x<=m 的解的个数 题解: 今天一整天的时间大部分都在调这题Orz BSGS什么的还是太不熟了 我们可以用BSGS拓展版求出 ...

  2. Visual Studio Code 代理设置

    Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代码编辑器(包括 IDE),例如 Fron ...

  3. 我们是怎么做Code Review的

    前几天看了<Code Review 程序员的寄望与哀伤>,想到我们团队开展Code Review也有2年了,结果还算比较满意,有些经验应该可以和大家一起分享.探讨.我们为什么要推行Code ...

  4. Code Review 程序员的寄望与哀伤

    一个程序员,他写完了代码,在测试环境通过了测试,然后他把它发布到了线上生产环境,但很快就发现在生产环境上出了问题,有潜在的 bug. 事后分析,是生产环境的一些微妙差异,使得这种 bug 场景在线下测 ...

  5. 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM

    刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...

  6. 在Visual Studio Code中配置GO开发环境

    一.GO语言安装 详情查看:GO语言下载.安装.配置 二.GoLang插件介绍 对于Visual Studio Code开发工具,有一款优秀的GoLang插件,它的主页为:https://github ...

  7. 代码的坏味道(14)——重复代码(Duplicate Code)

    坏味道--重复代码(Duplicate Code) 重复代码堪称为代码坏味道之首.消除重复代码总是有利无害的. 特征 两个代码片段看上去几乎一样. 问题原因 重复代码通常发生在多个程序员同时在同一程序 ...

  8. http status code

    属于转载 http status code:200:成功,服务器已成功处理了请求,通常这表示服务器提供了请求的网页 404:未找到,服务器未找到 201-206都表示服务器成功处理了请求的状态代码,说 ...

  9. Visual Studio Code——Angular2 Hello World 之 2.0

    最近看到一篇用Visual Studio Code开发Angular2的文章,也是一篇入门教程,地址为:使用Visual Studio Code開發Angular 2專案.这里按部就班的做了一遍,感觉 ...

随机推荐

  1. 【洛谷 P3191】 [HNOI2007]紧急疏散EVACUATE(二分答案,最大流)

    题目链接 sb错误调了3hour+.. bfs预处理出每个\(.\)到每个\(D\)的最短距离. 二分时间\(t\),把每个\(D\)拆成\(t\)个点,这\(t\)个点两两连边,流量\(INF\)表 ...

  2. 2017ACM暑期多校联合训练 - Team 2 1001 HDU 6045 Is Derek lying? (模拟)

    题目链接 Problem Description Derek and Alfia are good friends.Derek is Chinese,and Alfia is Austrian.Thi ...

  3. NB二人组(一)----堆排序

    堆排序前传--树与二叉树简介 特殊且常用的树--二叉树  两种特殊的二叉树 二叉树的存储方式 二叉树小结 堆排序 堆这个玩意....... 堆排序过程: 构造堆: 堆排序的算法程序(程序需配合着下图理 ...

  4. java在CMD窗口执行程序的时候输入密码(隐藏一些敏感信息)

    有时候我们需要从CMD窗口执行一些命令,有时候会输入一些敏感的信息,比如密码之类的东西,所以我们可以从控制台读取但是不希望别人看见我们的密码: import java.io.Console; /** ...

  5. caffe Python API 之Inference

    #以SSD的检测测试为例 def detetion(image_dir,weight,deploy,resolution=300): caffe.set_mode_gpu() net = caffe. ...

  6. MAC 文件被锁定

    从windows拷贝到MAC的文件,有时候会被锁定.右键-简介-已锁定也是灰色的,无法取消: xattr -l 文件名 xattr -d com.apple.FinderInfo 文件名

  7. DNS区域传送漏洞的安全案例

      DNS区域传送(DNS zone transfer)指的是一台备用服务器使用来自主服务器的数据刷新自己的域(zone)数据库.这为运行中的DNS服务提供了一定的冗余度,其目的是为了防止主的域名服务 ...

  8. 使用亚马逊云服务器EC2做深度学习(一)申请竞价实例

    这是<使用亚马逊云服务器EC2做深度学习>系列的第一篇文章. (一)申请竞价实例  (二)配置Jupyter Notebook服务器  (三)配置TensorFlow  (四)配置好的系统 ...

  9. linux shell 正则表达式(BREs,EREs,PREs)的比较

    原文 :   linux shell 正则表达式(BREs,EREs,PREs)差异比较 在使用 linux shell的实用程序,如awk,grep,sed等,正则表达式必不可少,他们的区别是什么 ...

  10. Web前端开发最佳实践(3):前端代码和资源的压缩与合并

    一般在网站发布时,会压缩前端HTML.CSS.JavaScript代码及用到的资源文件(主要是图片文件),目的是加快文件在网络中的传输,让网页更快的展现.当然,CDN分发.缓存等方式也是加快代码或资源 ...