题意:

给出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的更多相关文章

  1. 【Trie】Secret Message 秘密信息

    [题目链接]: https://loj.ac/problem/10054 [题意] 我认为这个题目最难的是题意: 其实分了两种情况: 1.如果当前文本串匹配不完,那么答案的是:匹配过程中遇到的模式串结 ...

  2. 【记录】EF Code First 实体关联,如何添加、修改实体?

    在使用 EF Code First 的时候,我们经常会对项目中的 Entry 进行一对多.多对多的映射配置,这时候就会产生主实体和子实体的概念,我们在添加.修改他们的时候,有时候会产生一些问题,比如添 ...

  3. 【LeetCode】Gray Code

    Gray Code The gray code is a binary numeral system where two successive values differ in only one bi ...

  4. 【leetcode】Gray Code (middle)

    The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...

  5. 【题解】【排列组合】【回溯】【Leetcode】Gray Code

    The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...

  6. 【Idea】idea code style配置eclipse code formatter

    在eclipse中有自动配置code style的功能 ,但是idea上却没有,这个时候需要自己手工配置 1. 在idea中找到Preference->Plugins->Browse re ...

  7. 【转】PowerDesigner code、name显示设置 及 同时显示办法

    原文地址:http://blog.csdn.net/fy_hanxu/article/details/52468927 菜单->Tool->Model Options->Name C ...

  8. 【EF】EF Code First Migrations数据库迁移

    1.EF Code First创建数据库 新建控制台应用程序Portal,通过程序包管理器控制台添加EntityFramework. 在程序包管理器控制台中执行以下语句,安装EntityFramewo ...

  9. 【Leetcode】【Medium】Gray Code

    The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...

随机推荐

  1. 深入浅出ShellExecute

    Q: 如何打开一个应用程序? ShellExecute(this->m_hWnd,"open","calc.exe",""," ...

  2. POJ3207+tarjan+2-sat

    /* 2-sat 题意:给定一个圆,圆上一些点.两点一线.现给出一些线,这些线可以在圆内连起来,也可以在圆外. 问有没有可能所有的线画完 且 不出现相交. 思路:把线画在圆内或圆外 看成一个组合.其它 ...

  3. 解决ListView 跟ScroolView 共存 listItem.measure(0, 0) 空指针

    在网上找到ListView 和ScroolView 共存的方法无非是给他每个listview 重新增加高度,但是android 的设计者始终认为这并不是一种好的实现方法.但是有的时候有必须要用这种蛋疼 ...

  4. cocos2d-x 锚点,位置==》动手实验记录 多动手... :)

    总结: 1:cocos2d-x的位置由锚点和Position位置 共同决定的.2: cocos2d-x,当位置不设置或者为零的时候, 子节点的锚点位置永远位于父节点的左小角的地方3:我们的自己的游戏编 ...

  5. Nginx-location配置指南

    语法规则: location [=|~|~*|^~] /uri/ { … } = 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可.nginx不对url做编码,因 ...

  6. GB2312 简体中文编码表

    GB 2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号.这种表示方式也称为区位码. 01-09区为特殊符号. 16-55区为一级汉字,按拼音排序. 56-87区为二级汉字,按部首/笔画 ...

  7. NFC(12)使用Android Beam技术传输文本数据及它是什么

    Android Beam技术是什么 Android Beam的基本理念就是两部(只能是1对1,不可像蓝牙那样1对多)NFC设备靠近时(一般是背靠背),通过触摸一部NFC设备的屏幕,将数据推向另外一部N ...

  8. C#中string.Format()和ToString()格式化方法

    C#数字格式化输出是我们在编程中经常需要处理的事情,那么这里向你介绍了一些C#数字格式化输出的例子,这样就会方便你来选择和比较,什么方式是比较适合自己项目的. int a = 12345678; C# ...

  9. Android2.3.7源码结构分析

    对Andorid系统进行分析或者系统功能定制的时候,我们经常需要在众多文件中花费大量时间定位所需关注的部分.为了减轻这部分枯燥而不可避免的工作,本文对2.3.7版本的源码结构进行了简单分析.希望对刚加 ...

  10. ogg实现oracle到sql server 2005的同步

    一.源端(oracle)配置1.创建同步测试表create table gg_user.t01(name varchar(20) primary key);create table gg_user.t ...