CF1059C Sequence Transformation

题意翻译

题目大意:

读入一个正整数n。 你有一个长度为n的排列。 对于一次操作,我们需要做一下几步:

  1. 将目前序列内所有数的gcd加入答案中
  2. 将序列内随意删除一个数
  3. 如果序列为空,则停止操作,否则重复以上步骤 操作完毕后,我们将会得到一个答案序列。 请输出字典序最大的那一个答案序列

题目描述

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

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 n n n integers: the greatest common divisors of all the elements in the sequence before each deletion.

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

A sequence a1,a2,…,an a_1, a_2, ldots, a_n a1,a2,,an is lexicographically larger than a sequence b1,b2,…,bn b_1, b_2, ldots, b_n b1,b2,,bn , if there is an index i i i such that aj=bj a_j = b_j aj=bj for all j<i j < i j<i , and ai>bi a_i > b_i ai>bi .

输入输出格式

输入格式:

The first and only line of input contains one integer n n n ( 1≤n≤106 1le nle 10^6 1n106 ).

输出格式:

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

输入输出样例

输入样例#1: 
3
输出样例#1: 
1 1 3 
输入样例#2: 
2
输出样例#2: 
1 2 
输入样例#3: 
1
输出样例#3: 
1 

说明

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

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

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

Solution:

  模拟考试时的送分题。

  打表找出规律,先删所有的奇数,共$lceil frac{n}{2} ceil$个$1$,设每次删完还剩下$k$个数,答案是共$lceil frac{k}{2} ceil$个$2^{k-1}$,最后还要判断$n$的各种情况,答案为$2^k$或$2^{k+1}$或$2^{k-1}*3$(貌似我写的很复杂,别人的思路应该会简单些)。

代码:

/*Code by 520 -- 10.15*/
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=5e6+5;
int n,a[N];

int main(){
    while(scanf("%d",&n)==1&&n){
        if(n==1) {puts("1");continue;}
        if(n==2) {puts("1 2");continue;}
        if(n==3) {puts("1 1 3");continue;}
        int m=n,num=1;
        while(m!=1){
            int p=(m+1)/2;
            For(i,1,p) printf("%d ",num);
            num*=2;
            m-=p;
        }
        int k=3;num=1;
        while((1<<num)<n) num++;
        if((1<<num)==n) printf("%d
",n);
        else {
            num--;
            if((1<<num-1)*3>n) printf("%d
",(1<<num));
            else{
                while((1<<num)*3<n) num--;
                printf("%d
",(1<<num-1)*3);
            }
        }
    }
    return 0;    
}
原文地址:https://www.cnblogs.com/five20/p/9853018.html