【CF476D】Dreamoon and Sets(构造)

点此看题面

  • 给定(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
}
败得义无反顾,弱得一无是处
原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF476D.html