有T个输入。
每组输入给出两个正整数 a , b ( a , b ≤ 2 × 1 0 6 ) a,b(a,b\leq 2 × 10^6) a,b(a,b≤2×106)。
请找到四个正整数 c , d , e , f ( f < b , d < b , 1 ≤ c , e ≤ 4 × 1 0 12 ) c,d,e,f(fc,d,e,f(f<b,d<b,1≤c,e≤4×1012),使他们满足:
c d − e f = a b \frac{c}{d}-\frac{e}{f}=\frac{a}{b} dc−fe=ba
如果有多组数据,输出其中一组。如果不存在,输出“-1 -1 -1 -1”。
3
4 1
1 6
37 111
-1 -1 -1 -1
1 2 1 3
145 87 104 78
首先显然,当 g c d ( a , b ) gcd(a,b) gcd(a,b)不为1时,我们可以令 a ′ = a g c d ( a , b ) , b ′ = b g c d ( a , b ) a'=\frac{a}{gcd(a,b)},b'=\frac{b}{gcd(a,b)} a′=gcd(a,b)a,b′=gcd(a,b)b。构造
a ′ + 1 b ′ − 1 b ′ = a b \frac{a'+1}{b'}-\frac{1}{b'}=\frac{a}{b} b′a′+1−b′1=ba
所以输出"a’+1 b’ 1 b’"即可。
当 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1时,易知
c d − e f = c f − d e d f \frac{c}{d}-\frac{e}{f}=\frac{cf-de}{df} dc−fe=dfcf−de
即 d f = k b df=kb df=kb(k为正整数)
首先我们可以证明一下结论:
结论①: b b b不能是质数或1。
证明:
b不能是1显然。
假设 b b b是质数,那 b b b的因子只有 1 , b 1,b 1,b,即 d , f d,f d,f只能分别取1和b的倍数,这与 d < b , f < b dd<b,f<b矛盾。故①得证。
结论②: b b b不能是质数幂(即 p k p^k pk)
证明:
假设 b = p k b=p^k b=pk,设 d = p a d=p^a d=pa,则 f = p k − a f=p^{k-a} f=pk−a,由扩展欧几里得得知 c f − d e = a cf-de=a cf−de=a有正整数解的充要条件是 g c d ( d , f ) ∣ a gcd(d,f)|a gcd(d,f)∣a故 g c d ( d , f ) = p m i n { a , k − a } gcd(d,f)=p^{min\{a,k-a\}} gcd(d,f)=pmin{a,k−a}。但因为 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,故 a a a的质因子里没有 p p p,即 g c d ( d , f ) ∤ a gcd(d,f)\nmid a gcd(d,f)∤a,矛盾。故②得证。
由结论①②可知结论③: b b b的质因子至少拥有两个。
根据③,我们设 b = ∑ i = 1 m p i k i b=\sum_{i=1}^{m}p_{i}^{k_i} b=∑i=1mpiki,令 d = p 1 k 1 , f = b / d , d=p_{1}^{k_1},f=b/d, d=p1k1,f=b/d,易知 g c d ( d , f ) = 1 gcd(d,f)=1 gcd(d,f)=1
故 c f − d e = a cf-de=a cf−de=a必有解,可以用扩展欧几里得求出 c , e c,e c,e。
需要注意的是,如果最后 c < 0 , e > 0 c<0,e>0 c<0,e>0,其实不需要对扩展欧几里得的解做一些操作,只需要调换 c / d , e / f c/d,e/f c/d,e/f的位置即可。
#include
using namespace std;
const int MAXN=5e6;
int prime[1000];//素数数组
bool is_prime[MAXN+10];//is_pri[i]表示i是否是素数
int sieve()//埃式筛
{
int n=MAXN;
int p=0;
for(int i=0; i<=n; i++)
is_prime[i]=true;
is_prime[0]=is_prime[1]=false;
is_prime[2]=true;
for(int i=2; i<=sqrt(n); i++)
{
if (is_prime[i])
{
prime[++p]=i;
for(int j=2*i; j<=n; j+=i)
is_prime[j]=false;
}
}
return p;
}
long long extended_gcd(long long a, long long b, long long &x, long long &y)
//扩展gcd
{
long long r, t;
if (b==0)
{
x=1;
y=0;
return a;
}
r=extended_gcd(b, a%b, x, y);
t=x;
x=y;
y=t-(a/b)*y;
return r;
}
long long solve_exgcd(long long a, long long b, long long c, long long &x, long long &y)
{
long long p=extended_gcd(a, b, x, y);
if (c%p)
{
x=-1;
y=-1;
return -1;
}
x*=(c/p);
y*=(c/p);
return 0;
}
void solve1()
{
long long pp=sieve();
int t;
scanf("%d", &t);
while(t--)
{
long long a, b;
scanf("%lld%lld", &a, &b);
if (__gcd(a, b)!=1)// ka/kb
{
long long v=__gcd(a, b);
a/=v;
b/=v;
printf("%lld %lld %lld %lld\n", a+1, b, 1, b);
continue;
}
else
{
if (b==1 || is_prime[b])//特判无解情况1
{
printf("-1 -1 -1 -1\n");
continue;
}
long long sum=0;
long long tmp,time=0;
long long bb=b;
for(int i=1;i<=pp && bb!=1;i++)
{
if(bb%prime[i]==0)
{
tmp=prime[i];
while(bb%prime[i]==0)
{
bb/=prime[i];
time++;
}
break;
}
}
if(bb==1)//特判情况2
{
printf("-1 -1 -1 -1\n");
continue;
}
long long d=1;
for(int i=1; i<=time; i++)
{
d*=tmp;
}
// printf("d=%lld\n",d);
long long f=bb;
long long c=0, e=0;
solve_exgcd(f, d, a, c, e);
if (c<0 && e>0)
printf("%lld %lld %lld %lld\n", e, f, -c, d);//两个调过来
else
printf("%lld %lld %lld %lld\n", c, d, -e, f);
}
}
}
int main()
{
// ios_base::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
#ifdef ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
long long test_index_for_debug=1;
char acm_local_for_debug;
while(cin>>acm_local_for_debug)
{
cin.putback(acm_local_for_debug);
if (test_index_for_debug>100)
{
throw runtime_error("Check the stdin!!!");
}
auto start_clock_for_debug=clock();
solve1();
auto end_clock_for_debug=clock();
cout<<"\nTest "<<test_index_for_debug<<" successful"<<endl;
cerr<<"Test "<<test_index_for_debug++<<" Run Time: "
<<double(end_clock_for_debug-start_clock_for_debug)/CLOCKS_PER_SEC<<"s"<<endl;
cout<<"--------------------------------------------------"<<endl;
}
#else
solve1();
#endif
return 0;
}
赛时差一点就对了…
感谢赛后蔡队的指点 (CSLNB!)
DrGilbert 2020.7.18