0
点赞
收藏
分享

微信扫一扫

P2485 [SDOI2011]计算器(扩欧&BSGS)

P2485 [SDOI2011]计算器(扩欧&BSGS)

1.快速幂

2.扩展欧几里得

3.BSGS(注意特判无解和特殊情况)。

​y%p==0 && z%p==0​​ x的最小值就是1.

​y%p=0 && z​​ 是无解。

貌似第一问不需要用扩展欧拉定理qwq。

// Problem: P2485 [SDOI2011]计算器
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2485
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// Date: 2022-06-01 12:07:40
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = {402653189,805306457,1610612741,998244353};
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\n",a[n]);
}
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y){
if(x<y) x=y;
}
template <typename T>
void cmn(T &x,T y){
if(x>y) x=y;
}
int phi(int n){ //求phi(n)
int s=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
s-=s/i;
while(n%i==0) n/=i;
}
}
if(n>1) s-=s/n;return s;
}
ll ksm(ll a,ll n,ll m=mod){
ll ans=1;
while(n){
if(n&1) ans=ans*a%m;
a=a*a%m;
n>>=1;
}
return ans;
}
ll exgcd(ll a,ll b,ll &x,ll &y){ //返回值是最大公约数.
if(b==0){
x=1,y=0;
return a;
}
ll ans=exgcd(b,a%b,x,y); //b和a%b的最大公约数等于a和b的最大公约数 所以直接返回ans
ll tmp=x; //这里求解的是 bx1+(a%b)y1=gcd ay1+b(x1-a/by1)=gcd x=y1, y=x1-a/b*y1
x=y;
y=tmp-a/b*y;
return ans;
}
ll BSGS(ll a,ll b,ll m){
unordered_map<ll,ll>mp;
ll r=b*a%m,t=sqrt(m)+1;
for(int B=1;B<=t;B++){
mp[r]=B;
r=(r*a)%m;
}
ll at=ksm(a,t,m),l=at;
for(int A=1;A<=t;A++){
if(mp[l]) return A*t-mp[l];
l=(l*at)%m;
}
return -1;
}
int main(){
int n,k;
scanf("%d%d",&n,&k);
int y,z,p;
if(k==1){
while(n--){
scanf("%d%d%d",&y,&z,&p);
ll m = phi(p);
z = z%m+m;
printf("%lld\n",ksm(y,z,p));
}
}
else if(k==2){
while(n--){
scanf("%d%d%d",&y,&z,&p);
ll u,v;
ll g = exgcd(y,p,u,v);
if(z%g){
puts("Orz, I cannot find x!");
continue;
}
ll c = p/g;
ll t = z/g;
u*=t;
printf("%lld\n",(u%c+c)%c);
}
}
else if(k==3){
while(n--){
scanf("%d%d%d",&y,&z,&p);
if((y%p==0) && (z%p==0)){
puts("1");
continue;
}
if((y%p==0)&&z){
puts("Orz, I cannot find x!");
continue;
}
ll val = BSGS(y,z,p);
if(val==-1) puts("Orz, I cannot find x!");
else printf("%lld\n",val);
}
}
return 0;
}


举报

相关推荐

0 条评论