卧薪尝胆,厚积薄发。
小Y的数论题
Date: Sun Aug 26 09:53:07 CST 2018 In Category: NoCategory

Description:

已知 $m,a,b,c$ ,构造 $x,y,z$ 使得 $x^a+y^b=z^c(mod\ m)$
$1\le m,a,b,c\le 10^9,1\le t \le 100000$

Solution:

只要构造一组就行了。
设 $x=2^{bk},y=2^{ak}$ ,则左边 $=2^{abk+1}$ 。
于是要构造 $z^c=2^{abk+1}$ ,设 $z=2^l$ ,于是 $2^{lc}=2^{abk+1}$ ,即 $lc=abk+1$ , $l,k$ 必须是非负整数。
于是扩欧解出来即可。
不过如果 $m=2^w$ ,即 $m$ 是 $2$ 的幂,那么特判。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
ll m,a,b,c;
ll power(ll a,ll b)
{
ll res = 1;
while(b > 0)
{
if(b & 1)res = res * a % m;
a = a * a % m;
b = b >> 1;
}
return res;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b == 0)
{
x = 1;y = 0;
return;
}
exgcd(b,a % b,x,y);
ll k = x;
x = y;y = k - a / b * y;
return;
}
void work()
{
scanf("%lld%lld%lld%lld",&m,&a,&b,&c);
ll t = log2(m);
ll x,y,z;
if(pow(2,t) == m)
{
x = 1;y = 1;z = 1;
if(a > 1)x = m / 2;
else if(b > 1)y = m / 2;
else if(c > 1){x = m / 2;y = m / 2;z = m / 2;}
else {x = y = 1;z = 2;}
printf("%lld %lld %lld\n",x,y,z);
return;
}
ll l,k;
exgcd(c,a * b,l,k);k = -k;
while(l < 0 || k < 0){l += a * b;k += c;}
x = power(2,b * k);y = power(2,a * k);z = power(2,l);
printf("%lld %lld %lld\n",x,y,z);
return;
}
int main()
{
int testcases;
scanf("%d",&testcases);
while(testcases--)work();
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡