BZOJ1467_Pku3243 clever Y_EXBSGS

Posted fcwww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1467_Pku3243 clever Y_EXBSGS相关的知识,希望对你有一定的参考价值。

BZOJ1467_Pku3243 clever Y_EXBSGS

Description

小Y发现,数学中有一个很有趣的式子: X^Y 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

 


 

exbsgs模板题,用来处理模数非质数的情况。

具体实现比较简单,注意前num个数需要枚举。

挖坑待填...

 

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <math.h>
using namespace std;
typedef long long ll;
map<ll,int>mp;
void exgcd(ll a,ll b,ll &x,ll &y,ll &p) {
    if(!b) {x=1; y=0; p=a; return ;}
    exgcd(b,a%b,y,x,p);
    y-=a/b*x;
}
ll gcd(ll x,ll y) {
    return y?gcd(y,x%y):x;
}
ll EXBSGS(ll a,ll b,ll n) {
    if(n==1) return b==0?0:-1;
    if(a%n==0) return b==0?0:1;
    mp.clear();
    ll r,D=1,num=0,now,base=1;
    while((r=gcd(a,n))>1) {
        if(b%r) return -1;
        num++; b/=r; n/=r; D=D*a/r%n;
    }
    int i;
    for(i=0,now=1;i<num;i++,now=now*a%n)
        if(now==b) return i;
    ll m=ceil(sqrt(n));
    for(i=0;i<m;i++) {
        if(!mp.count(base)) mp[base]=i;
        base=base*a%n;
    }
    ll x,y,p;
    for(i=0;i<m;i++) {
        exgcd(D,n,x,y,p);
        x=(x*b%n+n)%n;
        if(mp.count(x)) return i*m+mp[x]+num;
        D=D*base%n;
    }
    return -1;
}
int main() {
    ll a,b,n;
    while(scanf("%lld%lld%lld",&a,&n,&b)!=EOF) {
        if(a==0&&b==0&&n==0) return 0;
        ll ans=EXBSGS(a,b,n);
        if(ans==-1) puts("No Solution");
        else printf("%lld\n",ans);
    }
}

 

以上是关于BZOJ1467_Pku3243 clever Y_EXBSGS的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1467/2480Pku3243 clever Y/Spoj3105 Mod EXBSGS

BZOJ 3243 Clever Y

POJ3243 Clever Y大步小步法

POJ3243:Clever Y——题解

Clever Y POJ - 3243 (扩展BSGS)

POJ 3243Clever Y 拓展BSGS