poj2417大步小步法
来源:互联网 发布:python 中文字符串 编辑:程序博客网 时间:2024/05/21 03:17
当n是素数时
a^x≡b (mod n)
令x=im+j,m=ceil(sqrt(n)) 0<=i,j<m
a^j≡b*(a^(-m))^i mod(n)
用hash表存储a^0,a^1……a^(m-1),枚举i,找是否存在对应的j,存在即有解
n不是素数之所以不成立是因为(a,n)!=1导致逆元不存在。
a^x-kn=b;
当n不是素数时,设gcd=gcd(a,n),若gcd不能整除b,则无解
否则两端同时除以gcd,重复此步骤
#include<string.h>#include<stdio.h>#include<iostream>#include<cmath>#include<algorithm>using namespace std;struct node{ int num; long long val;}a[1000000];bool cmp(node x,node y){ return x.val==y.val?x.num<y.num:x.val<y.val;}int mod,m,cnt;int pow_mod(int a,int b){ long long t=a,res=1; while(b){ if(b&1) res=res*t%mod; t=t*t%mod; b>>=1; } return res;}int find(int n){ int l=0,r=cnt,mid; while(r>l+1){ mid=(l+r)>>1; if(a[mid].val<=n) l=mid; else r=mid; } if(a[l].val==n) return a[l].num; else return -1;}int main(){ int p,b; long long n; while(scanf("%d%d%I64d",&p,&b,&n)!=EOF){ if(n==1){ printf("0\n"); continue; } mod=p; m=ceil(sqrt(1.0*p)); int ni=pow_mod(pow_mod(b,p-2),m); a[0].val=1; a[0].num=0; for(int j=1;j<m;j++){ a[j].val=a[j-1].val*b%p; a[j].num=j; } sort(a,a+m,cmp); cnt=1; for(int j=1;j<m;j++){ if(a[j].val!=a[cnt-1].val){ a[cnt++]=a[j]; } } int i,j=-1; for(i=0;i<=m;i++){ j=find(n); if(j!=-1) break; n=n*ni%p; } if(j==-1){ printf("no solution\n"); continue; } long long ans=i*m+j; printf("%I64d\n",ans); }}
阅读全文
0 0
- poj2417大步小步法
- Poj2417 大步小步算法
- 大步小步法解决离散对数问题 by——miskcoo
- Summer Training day4 Mod Tree 大步小步法求离散对数模板
- poj2417
- 我的小一步,争取是人类的一大步
- poj2417 Discrete Logging
- [POJ2417]Discrete Logging
- poj2417 Discrete Logging
- LA 7457 Discrete Logarithm Problem(shank的大步小布算法)
- 购茶四步法
- 羽毛球步法
- 随机步法
- 迈了一大步
- 每天进步一大步...
- 迈进了一大步
- hdu 2815 大步小步
- 工作大步迈进。泊
- 51Nod 1005 大数加法
- Android语音用户引导:播放assets中的音频资源
- STL(十九)queue队列容器
- 索引
- IO和NIO的比较
- poj2417大步小步法
- Spark task not serializable错误的分析和处理
- CTreeCtrl获取根节点
- C++输入获取未知长度的行输入数组 与 输出控制
- linux运用vim编写C风格的代码
- mysql总结
- JQuery EasyUI 之Layout布局组件小Demo
- 单链表逆置
- Tyvj1037