隐藏页面特效

poj3243 Clever Y[扩展BSGS]

Clever Y
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 8666   Accepted: 2155

Description

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

XY mod Z = K

Given XYZ, we all know how to figure out K fast. However, given XZK, 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 XZK (0 ≤ XZK ≤ 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

Source

 
//消除因子,在做普通的BSGS #include<cmath> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; struct Thash{ static const ll N=1e6+5,MOD=233333; ll tot,val[N],h[N],next[N],head[MOD+100]; void clear(){tot=0;memset(head,0,sizeof head);} void insert(ll H,ll VAL){ for(ll i=head[H%MOD];i;i=next[i]) if(h[i]==H){val[i]=VAL;return ;} h[++tot]=H;val[tot]=VAL;next[tot]=head[H%MOD];head[H%MOD]=tot; } ll get(ll H){ for(ll i=head[H%MOD];i;i=next[i]) if(h[i]==H) return val[i]; return -1; } }M; ll gcd(ll a,ll b){ if(!b) return a; return gcd(b,a%b); } void exgcd(ll a,ll b,ll &d,ll &x,ll &y){ if(!b){d=a;x=1;y=0;return ;} exgcd(b,a%b,d,y,x); y-=a/b*x; } ll inv(ll a,ll p){ ll d,x,y; exgcd(a,p,d,x,y); return d==1?(x%p+p)%p:-1; } ll BSGS(ll a,ll b,ll mod){ M.clear(); ll m=(ll)ceil(sqrt(mod+0.5)); ll t=1; for(ll i=0;i<m;i++){ M.insert(t,i); t=t*a%mod; } ll base=inv(t,mod); ll res=b; for(ll i=0,z;i<m;i++){ if((z=M.get(res))!=-1) return i*m+z; res=res*base%mod; } return -1; } ll solve(ll a,ll b,ll mod){ ll A=1,D=1,cnt=0,ans; for(int i=0;i<=50;i++){ if(A==b) return i; A=A*a%mod; } for(ll t;(t=gcd(a,mod))!=1;){ if(b%t)return -1; b/=t; mod/=t; D*=a/t;D%=mod; cnt++; } b=b*inv(D,mod)%mod; ans=BSGS(a,b,mod); if(~ans) return ans+cnt; return -1; } int main(){ ll a,b,c,ans; while(~scanf("%lld%lld%lld",&c,&a,&b)){ ans=solve(a,b%c,c); if(~ans) printf("%lld\n",ans); else puts("no solution"); } return 0; }

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/6598929.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(348)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示