您的位置:首页 > 其它

数论其他算法的综合运用

2009-03-10 23:10 375 查看
/*
hdu 2815
zstu 1815
pku 3243
hust 1234
b^x=n(mod p)
给定b,n,p
计算经最值,or输出no solution
*/
#include<stdio.h>
#include<math.h>
#include<map>
#include<stdlib.h>
#include<iostream>
#include<cmath>
#include<time.h>
using namespace std;

struct z
{
int re,times;
}num[1000000];

__int64 p,b,n;
//排序
int cmp(const void*a,const void*b)
{
if(((struct z*)a)->re!=((struct z*)b)->re)
return ((struct z*)a)->re-((struct z*)b)->re;
return ((struct z*)a)->times-((struct z*)b)->times;
}
//二分求幂
__int64 mod(__int64 b,__int64 m,__int64 p)
{
__int64 ret=1;
while(m)
{
if(m&1)
{
ret*=b;
ret%=p;
}
b*=b;
b%=p;
m>>=1;
}
return  ret;
}
//二分查找
__int64 B_S(__int64 x,__int64 h)
{
__int64 l,m;
__int64 best=-1;
l=0;
while(l<=h)
{
m=(l+h)>>1;
if(num[m].re<x)
l=m+1;
else if(num[m].re>x)
h=m-1;
else
{
l=m+1;
best=num[m].times;
}
}
return best;
}
int main()
{
__int64 i,m,j,bm,x;
__int64 fac,find;
__int64 T;
//scanf("%d",&T);
while(scanf("%I64d%I64d%I64d",&b,&p,&n)!=EOF&&(b||n||p))
{
//有的时候会用到下面这个,看具体情况
/*if(n>=p||p==0)
{
puts("No Solution");
continue;
}
*/

m=(int)(sqrt(p));
n%=p;
b%=p;
num[0].re=n;
num[0].times=0;
j=n;
//保存(i,b^i)mod p
for(i=1;i<=m;i++)
{
j*=b;
j%=p;
num[i].re=j;
num[i].times=i;
}
qsort(num,m+1,sizeof(num[0]),cmp);
bm=mod(b,m,p);
fac=1;

x=-1;
//枚举(a^m)^i mod p
for(i=1;i<=m;i++)
{
fac*=bm;
fac%=p;
find=B_S(fac,m);
if(find+1)
{
x=i*m-find;
break;
}
}
if(x!=-1)
{
//重判,保证结果正确
fac=mod(b,x,p);
if(fac==n)
printf("%I64d/n",x);
else if(fac*x%p==n)
printf("%I64d/n",x+1);
else
puts("No Solution");
}
else
puts("No Solution");
}
return 0;
}


baby-step qiant-step
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: