版权声明:欢迎大家转载,转载请标明出处。 https://blog.csdn.net/ylsoi/article/details/81874245
题目大意:
小Y喜欢研究数论,并且喜欢提一些奇怪的问题。
这天他找了三个两两互质的数a, b, c,以及另一个数m, 现在他希望找到三个(0, m)范围内的整数x, y, z,使得
思路:
这题竟然是一个构造题。
考虑构造使得式子化为
的形式,也就是
,
,然后用拓展欧几里得解出即可。
但是但是发现这一题在模的意义下答案可能会是0,也就是当m为
时。
不妨特殊处理,若a,b,c中有大于1的数,就可以让它等于
,然后就变成0了。
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
using namespace std;
void File(){
freopen("51nod1479.in","r",stdin);
freopen("51nod1479.out","w",stdout);
}
int T;
ll mod,a,b,c,x,y;
ll exgcd(ll m,ll n){
if(!n){x=1;y=0;return m;}
ll g=exgcd(n,m%n),tmp=x;
x=y; y=tmp-m/n*y;
return g;
}
ll qpow(ll base,ll cnt){
ll ret=1; base%=mod;
while(cnt){
if(cnt&1)ret=ret*base%mod;
base=base*base%mod;
cnt>>=1;
}
return ret;
}
void calc(){
ll g=exgcd(a*b,-c);
x=x*(-g); y=y*(-g);
x=(x%c+c)%c; if(!x)x=c;
y=(ll)((1+(__int128)x*a*b)/c);
if(y<=0){
ll d=ceil((-y*1.0)/(a*b));
x=x+d*c; y=y+d*a*b;
if(!y)x=x+c,y=y+a*b;
}
//x*a*b-y*c==-1 ? cout<<"Yes"<<endl : cout<<"No"<<endl;
printf("%lld %lld %lld\n",qpow(2,x*b),qpow(2,x*a),qpow(2,y));
//(qpow(qpow(2,x*b),a)+qpow(qpow(2,x*a),b))%mod==(qpow(qpow(2,y),c))%mod ? : cout<<"fuck"<<endl;
}
int main(){
File();
scanf("%d",&T);
while(T--){
scanf("%lld%lld%lld%lld",&mod,&a,&b,&c);
ll fuck=mod;
while(fuck%2==0)fuck/=2;
if(fuck==1){
if(a>1)printf("%lld %lld %lld\n",mod/2,1ll,1ll);
else if(b>1)printf("%lld %lld %lld\n",1ll,mod/2,1ll);
else if(c>1)printf("%lld %lld %lld\n",mod/2,mod/2,mod/2);
else printf("%lld %lld %lld\n",1ll,1ll,2ll);
}
else calc();
}
return 0;
}