【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 ...
随机推荐
- linux pts/0的含义
pts是所谓的伪终端或虚拟终端,具体表现就是你打开一个终端,这个终端就叫pts/0,如果你再打开一个终端,这个新的终端就叫pts /1.比如用who命令查询当前登录的用户,可以看到每个用户的TTY设备 ...
- windows中断与共享的连接(samba)
问题:window下当成功登录到samba服务器上的共享的目录的时候,若要是再系想登录此服务器上另外一个共享目录时,会弹出登录窗口. 但是不管输入的用户名和密码对错都会提示. “不允许一个用户使用一个 ...
- live555源码研究(三)------UsageEnvironment类
一.UsageEnvironment类作用 1,不使用的时候回收当前的使用环境. 2,对返回结果消息和错误消息的维护. 二.类UsageEnvironment继承关系图
- Android:为控件绑定监听器
为控件绑定监听器主要分为以下步骤: 1.获取代表控件的对象2.定义一个类,实现监听器接口3.生成监听器对象4.为控件绑定监听器对象 实例:Button按钮----监听器OnClickListener ...
- P44、面试题4:替换空格
题目:请实现一个函数,把字符串中的每个空格替换成“%20”.例如输入“We are happy.”,则输出“We%20are%20happy.”. 如果用java string类中提供的replace ...
- 推荐五款优秀的PHP代码重构工具
在软件工程学里,重构代码一词通常是指在不改变代码的外部行为情况下而修改源代码.软件重构需要借助工具完成,而重构工具能够修改代码同时修改所有引用该代码的地方.本文收集了五款出色的PHP代码重构工具,以帮 ...
- Complete The Pattern #6 - Odd Ladder
Complete The Pattern #6 - Odd Ladder Task: You have to write a function pattern which creates the fo ...
- unity3d游戏开发 —— 倒计时
using UnityEngine;using System.Collections; public class CoolTime : MonoBehaviour { // Use this for ...
- poj 3041 Asteroids (二分图的最大匹配 第一题)
题目:http://poj.org/problem?id=3041 题意:在某个n*n的空间内,分布有一些小行星,某人在里面打炮,放一枪后某一行或某一列的行星就都没了,让求最少的打炮数. 然后把每行x ...
- 函数flst_init
/** The null file address */UNIV_INTERN fil_addr_t fil_addr_null = {FIL_NULL, 0}; /***************** ...