【51nod1479】小Y的数论题(构造)(扩展欧几里得)

传送门


题解:

猜得到应该是没有无解的情况。

x = 2 p b , y = 2 p a , z = 2 ( p a b + 1 ) / c x=2^{pb},y=2^{pa},z=2^{(pab+1)/c} x=2pb,y=2pa,z=2(pab+1)/c即可得到一组合法解,但是注意到可能取 0 0 0就gg了。

对于 2 2 2的整数次幂,直接特判即可。


代码:

#include
#define ll long long
#define re register
#define gc get_char
#define cs const
#define int ll

namespace IO{
	inline char get_char(){
		static cs int Rlen=1<<18|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}
	
	template<typename T>
	inline T get(){
		char c;
		while(!isdigit(c=gc()));T num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
	inline int getint(){return get<int>();}
}
using namespace IO;

using std::cerr;
using std::cout;

int mod;
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline int power(ll b,int res=1){
	for(int a=2;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));
	return res;
}

inline void ex_gcd(ll a,ll b,ll &x,ll &y){
	if (!b){x=1,y=0;return;}
	ex_gcd(b,a%b,y,x);
	y-=a/b*x;
}

inline void solve(){
	mod=getint();int a=getint(),b=getint(),c=getint();
	int t=mod;
	while(t&&!(t&1))t>>=1;
	if(t>1){
		ll p,q;
		ex_gcd((ll)a*b,c,p,q);
		p=-p;
		while(p<0||q<0)p+=c,q+=(ll)a*b;
		cout<<power(p*b)<<" "<<power(p*a)<<" "<<power(q)<<"\n";
	}
	else {
		if(a>1)cout<<mod/2<<" 1 1\n";
		else if(b>1)cout<<"1 "<<mod/2<<" 1\n";
		else if(c>1)cout<<mod/2<<" "<<mod/2<<" "<<mod/2<<"\n";
		else cout<<"1 1 2\n";
	}
}

signed main(){
#ifdef zxyoi
	freopen("y.in","r",stdin);
#endif
	int T=getint();while(T--)solve();
	return 0;
}

你可能感兴趣的:(构造,_____数学_____)