1. 程式人生 > 實用技巧 >CF894C Marco and GCD Sequence|構造

CF894C Marco and GCD Sequence|構造

非常有趣的思維體操構造題。

顯然構造出來的序列不能出現給出序列以外的數,但是由於要求構造的數列可以是 \(4\) 倍於原序列,我們可以重複至多 \(4\) 次該序列的數。

現在直接給出一個構造方法:在原序列每個數後插入第一個數。即a[1] a[2] a[1] a[3] a[1]...a[n]

證明其正確性:

首先,要構造出該序列,原序列必須滿足對於 \(1\le i \le n\)\(a_i\)\(a_1\) 倍數

因為 \(a_1\) 一定是整個序列的GCD,否則 \(a_1\) 必定無法是序列中任何一段的GCD。

那麼,整個序列必定\(a_1\) 的倍數。若存在一個 \(a_i\)

不是 \(a_1\) 的倍數,則若存在這個序列,其中一段的GCD不是 \(a_1\) 的倍數,根據GCD的性質,這一段數向左,向右伸展,其GCD也必然不是 \(a_1\) 的倍數,那麼整個序列的GCD一定不是 \(a_1\)。與上面矛盾,不成立。若出現這種情況,輸出 -1 即可。

根據此性質,按照我們的構造方法,單一一個數的GCD是其本身,多個數由於 \(a_1\) 的存在,其GCD必定為 \(a_1\),符合題意。

上程式碼

#include<bits/stdc++.h>
using namespace std;
int n,a[1500];
int gcd(int x,int y)
{
	if (!y) return x;
	return gcd(y,x%y);
}
int main()
{
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
		if (gcd(a[i],a[1])!=a[1]) 
		{
			cout<<"-1\n";
			return 0;
		}
	}
	cout<<2*n-1<<endl;
	cout<<a[1]<<" ";
	for (int i=2;i<=n;i++) cout<<a[i]<<" "<<a[1]<<" ";
	return 0;
}