【bzoj 1467】Pku3243 clever Y(扩展BSGS)

来源:互联网 发布:java 1.8运行环境 编辑:程序博客网 时间:2024/05/16 08:42

1467: Pku3243 clever Y

Time Limit: 4 Sec Memory Limit: 64 MB
Submit: 213 Solved: 115
[Submit][Status][Discuss]
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

HINT
Source
ghy

【题解】【扩展BSGS模板题】
【扩展BSGS】
[http://blog.csdn.net/reverie_mjp/article/details/51233630]

#include<map>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define ll long longusing namespace std;map<ll,bool>h1;map<ll,ll>hash;ll n,m,p,ans;ll gcd(ll a,ll b){    if(!(a%b)) return b;     else return gcd(b,a%b);}ll poww(ll x,ll q,ll mod){    ll sum=1;    for(;q;q>>=1,x=x*x%mod)     if(q&1)  sum=sum*x%mod;    return sum;  }ll exbsgs(ll x,ll y,ll mod){    x%=mod,y%=mod;    if(y==1) return 0;    ll t=1,d=1,k=0;    while((t=gcd(x,mod))!=1)     {        if(y%t) return -1;        k++;        y/=t; mod/=t;        d=d*(x/t)%mod;        if(y==d) return k;     }//删公因数     h1.clear(); hash.clear();    ll mm=ceil(sqrt((double)mod));    ll sum=poww(x,mm,mod);    ll l=y; hash[l]=0; h1[l]=true;    for(ll i=1;i<=mm;++i)      {        l=l*x%mod;        hash[l]=i;        h1[l]=true;      }        for(ll i=1;i<=mm;++i)     {        d=d*sum%mod;        if(h1[d]) return i*mm-hash[d]+k;     }//BSGS     return -1;}int main(){    while(~(scanf("%lld%lld%lld",&n,&p,&m)))     {        if(!n&&!m&&!p) return 0;        ans=exbsgs(n,m,p);        if(ans==-1) printf("No Solution\n");         else printf("%lld\n",ans);     }    return 0;}
0 0
原创粉丝点击