1 条题解
-
0
本题解同步发表在博客。
老实了, 分钟秒掉的思路, 分钟写好的代码,结果调了 分钟。
首先题解的所有运算均在模 的情况下进行。
分析题目,定义 ,题目即求最小的 满足 。
先打表:
那么非常容易就可以得到:
又得知
代入 得:
即:
将 移到右边,得:
右边部分可以用逆元解决,然后聪明的小朋友就去用 BSGS 了,喜提 分。
连样例都过不去这是为什么呢?
因为 BSGS 只能解决 的情况。所以 得直接特判, 用 exgcd。
好了,现在有 分了。因为会出现 的情况,你还得特判。
最后就可以过了。
#include<bits/stdc++.h> using namespace std; #define int long long int bsgs(int a,int b,int p) { a%=p,b%=p;if(b==1)return 0; int m=ceil(sqrt(p)),am=1; unordered_map<int,int>f; for(int i=1;i<=m;i++)f[b*(am=am*a%p)%p]=i; for(int i=1,t=1;i<=m;i++)if(f.count(t=t*am%p))return i*m-f[t]; return -1; } void exgcd(int a,int b,int &d,int &x,int &y) { if(b==0){d=a,x=1,y=0;return;} exgcd(b,a%b,d,y,x); y-=a/b*x; } int qpow(int a,int b,int p){int ans=1;for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;return ans;} void solve() { int p,a,b,s,g;cin>>p>>a>>b>>s>>g; if(a==0) { if(s==g)cout<<0<<'\n'; else if(b==g)cout<<1<<'\n'; else cout<<-1<<'\n'; return ; } if(a==1) { int d,x,y,K=((g-s)%p+p)%p; exgcd(b,p,d,x,y); if(K%d!=0)cout<<-1<<'\n'; else { int dx=abs(p/d); x=(x*(K/d)%dx+dx)%dx; cout<<x<<'\n'; } return; } int p1=((a*g+b-g)%p+p)%p,p2=((a*s+b-s)%p+p)%p; if(p1==0&&p2==0)cout<<0<<'\n'; else if(p1!=0&&p2==0)cout<<-1<<'\n'; else { int ans=bsgs(a,(p1)%p*qpow(p2,p-2,p)%p,p); cout<<ans<<'\n'; } } signed main() { int t;cin>>t; while(t--)solve(); return 0; }
- 1
信息
- ID
- 10024
- 时间
- 4000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 8
- 已通过
- 2
- 上传者