【poj3243】Clever Y

xiaoxiao2021-02-28  49

Time Limit: 5000MS Memory Limit: 65536K

Description

Little Y finds there is a very interesting formula in mathematics: X^Y 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 ≤ 109). 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

Solution

扩展BSGS模板题,留作纪念,代码是我凭想象写的,不知有没有bug……

Code

#include<stdio.h> #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const ll mod=76543; ll k,x,y,z,top,hs[mod],id[mod],Last[mod],Next[mod]; ll GCD(ll a,ll b) { return !b?a:GCD(b,a%b); } void Insert(ll a,ll b) { ll c=a%mod; hs[++top]=a,id[top]=b,Next[top]=Last[c],Last[c]=top; } ll Find(ll a) { ll b=a%mod; for(ll i=Last[b];i;i=Next[i]) if(hs[i]==a) return id[i]; return -1; } ll Extended_BSGS(ll a,ll b,ll c) { ll d=1,r,cnt=0; for(ll i=0,j=1;i<=ceil(log2(c));i++,j=j*a%c) if(j%c==b) return i; while((r=GCD(a,c))!=1) { if(b%r!=0) return -1; b/=r,c/=r,d=d*a/r%c,cnt++; } ll m=sqrt(c),j=1,t=1,l; for(ll i=0;i<m;i++,j=j*a%c) Insert(j*b%c,i); for(ll i=m;i<=c;i+=m) if(~(l=Find(d*(t=t*j%c)%c))) return i-l+cnt; return -1; } int main() { while(~scanf("%lld%lld%lld",&x,&z,&k)&&(x||z||k)) { top=0,k%=z; memset(Last,0,sizeof(Last)); y=Extended_BSGS(x,k,z); if(~y) printf("%lld\n",y); else puts("No Solution"); } return 0; }
转载请注明原文地址: https://www.6miu.com/read-2620278.html

最新回复(0)