- 给定(n,k),要求构造(n)个四元组,满足没有数字重复出现,且同一四元组中的数两两(gcd)为(k)。
- 要求所有四元组中的最大值尽可能小。
- (nle10^4,kle100)
构造
由两两(gcd)为(k)这个限制,容易得出所有数都是(k)的倍数。
因此如果我们把所有数都除以(k),就变成要求满足同一四元组中的数两两互质。
一个基本事实,两个偶数是不可能互质的,所以一个四元组最理想状态下应该由一个偶数和三个奇数组成。
我们发现,三个连续的奇数(x,x+2,x+4)肯定互质(根据(gcd)的辗转相减性即可证明,因为(2,4)都不可能是一个奇数的因数)。
那么我们自然想到让前(3n)个奇数都出现在这(n)个四元组中,剩下的问题就是给每组配上一个偶数。
最优的情况肯定是(x+1)或(x+3),这里以(x+1)为例,(x+3)其实也同理可行。
显然(gcd(x,x+1)=gcd(x+1,x+2)=1),那么只要证明(x+1)和(x+4)互质。
由于(gcd(x+1,x+4)=gcd(3,x+4)),因此当且仅当(x+1)和(x+4)是(3)的倍数,它们不会互质。
但(x)是从(1)开始每三个奇数的第一个,也就必然可以表示成(6t+1)的形式,那么(x+1)和(x+4)分别是(6t+2,6t+5),不可能是(3)的倍数,故(x+1)和(x+4)互质。
因为这种构造方案充分利用了所有的奇数,肯定是最优解。
代码:(O(n))
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
using namespace std;
int n,k;
int main()
{
RI i,x;scanf("%d%d",&n,&k),printf("%d
",(6*n-1)*k);//充分利用所有奇数
for(i=x=1;i<=n;++i,x+=6) printf("%d %d %d %d
",x*k,(x+1)*k,(x+2)*k,(x+4)*k);return 0;//x x+1 x+2 x+4
}