1. 程式人生 > >C Sequence Transformation (思維gcd)

C Sequence Transformation (思維gcd)

C. Sequence Transformation

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Let's call the following process a transformation of a sequence of length nn.

If the sequence is empty, the process ends. Otherwise, append the greatest common divisor

 (GCD) of all the elements of the sequence to the result and remove one arbitrary element from the sequence. Thus, when the process ends, we have a sequence of nn integers: the greatest common divisors of all the elements in the sequence before each deletion.

You are given an integer sequence 1,2,…,n1,2,…,n. Find the lexicographically maximum result of its transformation.

A sequence a1,a2,…,ana1,a2,…,an is lexicographically larger than a sequence b1,b2,…,bnb1,b2,…,bn, if there is an index ii such that aj=bjaj=bj for all j<ij<i, and ai>biai>bi.

Input

The first and only line of input contains one integer nn (1≤n≤1061≤n≤106).

Output

Output nn integers  — the lexicographically maximum result of the transformation.

Note

In the first sample the answer may be achieved this way:

  • Append GCD(1,2,3)=1(1,2,3)=1, remove 22.
  • Append GCD(1,3)=1(1,3)=1, remove 11.
  • Append GCD(3)=3(3)=3, remove 33.

We get the sequence [1,1,3][1,1,3] as the result.

比賽時候真的沒讀明白題,以為隨便刪除元素,然後要輸出序列遞增這樣,結果wa的心累。

題目大意:

給你一個數字n,然後從從1,2,3......n這個序列中

依次進行以下操作:1 、求所有數的最大公因數,放入a序列裡面

         2 、任意刪去一個元素

一直到初始N序列為空,結束操作,列印這個a序列。

根據刪除元素的不同,導致序列a的字典序可能不同,

要求輸出字典序最大的a序列。

題解:

學到了兩個特性:

  1. gcd(a1,a2,a3,a4.....an)  <= min(a1,a2,a3,a4...an),所有數的gcd值一定小於所有數的最小值
  2. 任意兩個相鄰的數字gcd等於1,比如:gcd(4,5)= 1

咱們看序列,比如N=8:(  1  ,2   , 3  ,  4  ,5  ,6  ,7  ,8 )

先舉例8個數   首先,你這個開頭的1不刪除,你的gcd永遠不可能超過1,所以第一個刪除的數字就是這個1

其次,相鄰兩個數gcd等於1,為了讓gcd儘早的大於1,那麼對於3,5,7,我們都應該刪除(這時候不能刪除2,4,6,8,原因你可以自己思考),這樣會使gcd的值變大。

那麼就刪除3,5,7這3個元素

序列中生下了2,4,6,8這4個元素

這時gcd == 2,那麼你這個2不刪的話,你的gcd永遠不可能大於2,所以這個2,是要首先刪除的,

剩下4,6,8這三個元素,類比上面的刪除中間元素,刪除6

剩下兩個元素4,8 ,當序列中只剩下兩個元素的時候,先輸出兩個數gcd,然後輸出最大的數即可

總結一下就是:刪除1,3,5,7。。。。。

       刪除2,6,10 ,14 。。。。。

       刪除4 ,12,20,28 .。。。。

當然上面討論的都是偶數的情況,奇數的情況是否使用呢?

其實奇數的情況和偶數的情況是一樣的,無非就是1,2,3,4,5

刪除1,剩下2,3,4,5

其實就是先刪掉序列中奇數,然後偶數從小往大刪,輸出gcd即可。

#include <bits/stdc++.h>
using namespace std;
void dfs(int n,int x) {
	if (n<=3) {
		int i;
		for (i=1; i<n; i++) {
			printf("%d ",x);
		}
		printf("%d ",n*x);
		return;
	}
	int i;
	for (i=1; i<=n; i+=2) {
		printf("%d ",x);
	}
	dfs(n/2,x*2);
}
int main() {
	int n;
	scanf("%d",&n);
	dfs(n,1);
	return 0;
}