您的位置:首页 > 其它

[BZOJ2480]=[BZOJ2995]Spoj3105 Mod

2015-10-03 21:20 369 查看
原题地址

P不为素数的离散对数问题.

作死全部变量用ll+用map,结果:



时限是10s,好险啊差点就T了…

其实只有两数相乘再取模那里会爆int,于是我们类型转换一下就可以了(具体看代码).

结果:



还是好慢OLZ不过至少快了2s+…

AC code:

#include <cstdio>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;

int gcd(int x,int y){
return y?gcd(y,x%y):x;
}

int qpow(int x,int y,int p){
if(!y) return 1;
int z=qpow(x,y>>1,p);
z=(ll)z*z%p;
if(y&1) z=(ll)z*x%p;
return z;
}

void exgcd(int a,int b,int& x,int& y){
if(!b){
x=1;y=0;
return ;
}
exgcd(b,a%b,x,y);
int xx=x,yy=y;
x=yy;y=xx-(int)(a/b)*yy;
}

int getinv(int a,int p){
int inv,tmp;
exgcd(a,p,inv,tmp);
if(inv<0) return -((-inv)%p-p);
return inv%p;
}

int BSGS(int a,int p,int b){
int q=(int)sqrt(p),inv=getinv(qpow(a,q,p),p);
map<int,int> id;
for(int i=0,tmp=1;i<q;i++,tmp=(ll)tmp*a%p){
if(tmp==b) return i;
id[tmp]=i;
}
for(int i=1;i<=q;i++){
b=(ll)b*inv%p;
if(id[b]) return id[b]+i*q;
}
return -1;
}

int solve(int a,int p,int b){
for(int i=0,tmp=1;i<=100;i++,tmp=(ll)tmp*a%p) if(tmp==b) return i;
int i=0,k=1;
for(;;i++){
int g=gcd(a,p);
if(g==1){
b=(ll)b*getinv(k,p)%p;
break;
}
k=(ll)k*a/g%p;
p/=g;
if(b%g) return -1;
b/=g;
}
return BSGS(a,p,b)+i;
}

int main(){
while(1){
int a,p,b,ans;
scanf("%d%d%d",&a,&p,&b);
if(!(a|p|b)) break;
a%=p;b%=p;
ans=solve(a,p,b);
if(ans==-1) printf("No Solution\n");
else printf("%d\n",ans);
}

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