您的位置:首页 > 其它

Clever Y [Bzoj 1467]

2016-06-17 18:10 351 查看
题目地址请点击——

Clever Y

Description

小Y发现,数学中有一个很有趣的式子: XY mod Z = K 给出 X、Y、Z,我们都知道如何很快的计算 K。

但是如果给出 X、Z、K,你是否知道如何快速的计算 Y 呢?

Input

本题由多组数据(不超过20组),每组测试数据包含一行三个整数 X、Z、K(0≤X,Z,K≤109)。 输入文件一行由三个空格隔开的 0 结尾。

Output

对于每组数据:如果无解则输出一行 No Solution,否则输出一行一个整数 Y(0≤Y<Z),使得其满足 XY mod Z = K,如果有多个解输出最小的一个 Y。

Sample Input

5 58 33

2 4 3

0 0 0

Sample Output

9

No Solution

Solution

扩展 Baby-Step-Giant-Step 模板题。

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>

#define LL long long
#define HASH_MOD 786433

using namespace std;

LL x,z,k,cnt=0,xxx,yyy,ans;

LL ex_gcd(LL x,LL y,LL &a,LL &b){
if(y==0){a=1;b=0;return x;}
LL fa,fb;
LL c=ex_gcd(y,x%y,fa,fb);
a=fb;
b=fa-fb*(x/y);
return c;
}

struct map{
LL h[800000],v[800000],nxt[800000],ne[800000];
void clear(){
memset(nxt,-1,sizeof nxt);
memset(h,-1,sizeof h);
ne[786433]=0;
for(LL i=0;i<786433;i++)ne[i]=i;
}
LL fi(LL x){
LL tmp=x,pre;
while(tmp!=ne[tmp])tmp=ne[tmp];
while(x!=tmp){pre=ne[x];ne[x]=tmp;x=pre;}
return tmp;
}
void insert(LL x,LL y){
LL mx=x%HASH_MOD;
while(nxt[mx]!=-1)
mx=nxt[mx];
nxt[mx]=fi(0);
ne[nxt[mx]]=ne[nxt[mx]]+1;
h[nxt[mx]]=x;
v[nxt[mx]]=y;
}
LL find(LL x){
LL mx=x%HASH_MOD;
while(x!=h[mx]&&nxt[mx]!=-1)mx=nxt[mx];
if(x!=h[mx])return -1;
return v[mx];
}
};

map hash;

int main(){

while(scanf("%lld%lld%lld",&x,&z,&k)!=EOF&&(x||z||k)){
hash.clear();
LL gg=ex_gcd(x,z,xxx,yyy),d=1,MAXN,tmp,tmp2,tt;
while(gg!=1){
if(k%gg!=0){printf("No Solution\n");goto nxt;}
k/=gg;z/=gg;d*=x/gg;
cnt++;
gg=ex_gcd(x,z,xxx,yyy);
}
x%=z;k%=z;
MAXN=ceil(sqrt((double)z)),tmp=1;
if(k==d%z){printf("0\n");goto nxt;}
hash.insert(1,0);
for(LL i=1;i<MAXN;i++){
tmp=tmp*x%z;
if(d*tmp%z==k){
if(i<=cnt){printf("%lld\n",i);goto nxt;}
else{printf("%lld\n",i+cnt);goto nxt;}
}
hash.insert(tmp,i);
}
tmp2=tmp,tt=tmp*x%z;
for(LL i=MAXN;i<=cnt;i++){
tmp2=tmp2*x%z;
if(d*tmp%z==k){printf("%lld\n",i);goto nxt;}
}
tmp=tt;
if(d*tmp%z==k){
if(MAXN<=cnt){printf("%lld\n",MAXN);goto nxt;}
else{printf("%lld\n",MAXN+cnt);goto nxt;}
}
ex_gcd(d*tmp,z,xxx,yyy);
xxx=(xxx*k%z+z)%z;
if((ans=hash.find(xxx))!=-1){printf("%lld\n",ans+MAXN+cnt);goto nxt;}
for(LL i=2;i<=MAXN;i++){
tmp=tmp*tt%z;
ex_gcd(d*tmp,z,xxx,yyy);
xxx=(xxx*k%z+z)%z;
if((ans=hash.find(xxx))!=-1){printf("%lld\n",ans+MAXN*i+cnt);goto nxt;}
}
printf("No Solution\n");
nxt:;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: