您的位置:首页 > 其它

POJ 3243 Clever Y

2016-07-14 11:27 239 查看

 

 
Time Limit: 5000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

Description

Little Y finds there is a very interesting formula in mathematics:

XY mod Z = K

Given X, Y, Z, we all know how to figure out K fast. However, given X, Z, K, could you figure out Y fast?

Input

Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers X, Z, K (0 ≤ X, Z, K ≤ 10 9).
Input file ends with 3 zeros separated by spaces.

Output

For each test case output one line. Write "No Solution" (without quotes) if you cannot find a feasible Y (0 ≤ Y < Z). Otherwise output the minimum Y you find.

Sample Input

5 58 33
2 4 3
0 0 0

Sample Output

9
No Solution

Source

POJ Monthly--2007.07.08, Guo, Huayang

 

依旧是离散对数。

和POJ2417基本相同:

http://www.cnblogs.com/SilverNebula/p/5668380.html

不同之处是这道题的X Z K没有特殊限制,可能不是质数,传统的做法应该是不断转化式子直到gcd(a',n')==1 ,

然后再BSGS

代码参照Orion_Rigel的题解http://blog.csdn.net/orion_rigel/article/details/51893151

 

然而套用了之前2417的代码,发现能AC

也是神奇

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int mop=100007;
const int mxn=100020;
int hash[mxn],hd[mxn],id[mxn],next[mxn],cnt;

LL gcd(LL a,LL b){
return (b==0)?a:gcd(b,a%b);
}
void ins(LL x,LL y){
int k=x%mop;
hash[++cnt]=x;
id[cnt]=y;next[cnt]=hd[k];hd[k]=cnt;
return;
}
LL find(LL x){
int k=x%mop;
for(int i=hd[k];i;i=next[i]){
if(hash[i]==x)return id[i];
}
return -1;
}
LL BSGS(int a,int b,int n){
memset(hd,0,sizeof hd);
cnt=0;
if(!b)return 0;
int m=sqrt(n),i,j;
LL x=1,p=1;
for(i=0;i<m;i++,p=p*a%n)ins(p*b%n,i);
for(LL i=m;;i+=m){
x=x*p%n;
if((j=find(x))!=-1)return i-j;
if(i>n)break;
}
return -1;
}
int main(){
int x,z,k;
while(scanf("%d%d%d",&x,&z,&k)!=EOF){
if(!x && !z && !k)break;
int ans=BSGS(x,k,z);
if(ans==-1)printf("No Solution\n");
else printf("%d\n",ans);

}
return 0;
}

 

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