Luogu P11036 GCD 与 LCM 问题 [ 绿 ] [ 构造 ] [ 数论 ] [ adhoc ]
Luogu P11036 GCD 与 LCM 问题:梦熊的题真是又神又逆天。
思路
观察到有个奇数的特殊性质,我们尝试从奇数构造入手。
先来尝试带入极端数据,对于 \(\gcd\),我们可以把 \(b=1\) 的情况先带进去看看。
\[a+b+c+d=\gcd(a,b)+\operatorname{lcm}(c,d)
\]
\[a+1+c+d=1+\operatorname{lcm}(c,d)
\]
\[a+c+d=\operatorname{lcm}(c,d)
\]
奇数情况
我们尝试在 \(a\) 为奇数的情况解这个方程。
首先我们依然是进行极端构造,先把 \(c=1\) 带入,可得:
\[a+1+d=d
\]
发现 \(d\) 被消去,我们无法求出 \(d\),所以我们要让 \(d\) 的系数加倍,以防止被抵消。
于是我们尝试把 \(c=2\) 带入,并且强制让 \(d\) 变成奇数,这样才能让这个 \(2\) 起效果。
\[a+2+d=2d
\]
\[d=a+2
\]
其中,\(a,d\) 皆为奇数,所以成立。
所以:
\[b=1,c=2,d=a+2
\]
场上我只想得出这个奇数构造了,偶数的没有想出来。现在看来我就是个傻逼。
偶数情况
我们发现奇数情况是不适用偶数情况的,所以要另辟蹊径。
于是我们要想办法让偶数情况变成奇数情况。
怎么变?
尝试把 \(a\) 中所有的 \(2\) 提出来,\(a\) 就变成奇数了!
这时:
\[a=2^k*p
\]
其中 \(p\) 为奇数。
所以我们可以对 \(p\) 的情况进行构造,然后将 \(c,d\) 同时乘上 \(2^k\) 输出就好了。
为什么不会超过限制?因为 \(d\) 最多才 \(a+2\),也就是说他最多比 \(a\) 要大 \(2^30\),极端情况下也只有 \(2^{30}+2^{29}=1610612736\),刚好卡过!
注意 \(b\) 不用扩倍,因为他立刻就能被消去。
总结
这题其实重点在于考虑从特殊性质入手,然后进行极端构造,最后尝试把难以解决的情况化为之前我们以及解决了的问题。是一道很好的构造练习题。
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
int t;
ll a,b,c,tms;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
{
cin>>a;
tms=1;
while(a%2==0)
{
a/=2;
tms*=2;
}
cout<<1<<' '<<2*tms<<' '<<(a+2)*tms<<endl;
}
return 0;
}