无聊的序列 

题面

【问题描述】

​ MrKill上了高数之后超无聊,觉得好像很简单的样子。

​ 一天老师看他很不爽,下课约到了办公室(很抱歉现实中大学咩有老师会约你)。一张无限长的纸上,写了n个数,分别是1到n。老师觉得好像他全懂了,指着这张纸:“你知道GCD吗?我今天上课才讲的。”

“这还不简单???”

“那把这些n个数的GCD写下来”

老师随机删了一个数又这么问,反复了n-1次之后,只有一个数了,老师推了推眼镜,把这个数填在了你写的

序列的末尾。MrKill获得了传说道具——LS序列。

老师重新抽了一张无限长的纸写了n个数,分别是1到n。老师把笔给了你,让你也来动手删一删,然后写下

字典序最大的LS序列就让你放学。MrKill手足无措,满头大汗,他还想着马上赶去聚会呢。

​ 救救孩子。

【输入格式】

​ 输入文件名为 sequence.in。

​ 输入多个数表示n(小数据不超过50个、大数据不超过1个)读到0结束。

【输出格式】

输入文件名为 sequence.out。

​ 输出数据为多串长度为n的序列,代表字典序最大的LS序列

【输入输出样例1】

sequence.in sequence.out
3 1 1 3
2 1 2
1 1
0

样例1解释:

对于序列1、2、3

① 一个数没有删的时候\(GCD(1,2,3)= 1\)

② MrKill选择把2先删了发现没有什么用\(GCD(1,3)= 1\)

③ MrKill发现删了1可以变大\(GCD(3)= 3\)

他不知道怎么回事就做对了

【数据规模与约定】 (这道题我真的不知道怎么送分)

对于20%的数据\(n ≤ 10\)

对于60%的数据 \(n ≤ 1000\)

对于 100%的数据 \(n ≤ 5*10^6\)

题解

一道偏简单的性质构造题

我们考虑这样一个事实\(GCD \ ( a,a+1)= 1\),为了让字典序最大,我们需要尽快把相邻的两项清掉,但是删去

奇数还是偶数呢?当然是删奇数,因为偶数有共同的\(GCD=2\),奇数却不一定有共同的\(GCD\)。这样我们就保

证了最快使得非1元素出现,贪心使得字典序最大。

接下来怎么办呢?

我们把剩下的数除以2,再做一遍刚才一样的操作,利用一个计数器,记录除了多少个二或者直接记录\(2^k\) 这样,

一步一步除下来,就可以得到最终序列了。

然而这样处理到最后,需要判断\(n=1,2,3\)的情况,留给你们自己思考(考场上应该就做出来的)。

可能还有一些小朋友没理解,可以去和别人讨论讨论,这是一种相当典型的第一题用去奇数再除以2的序列递

归。除了序列递归,还有很多种可以利用除以2来解决的事情,可以考虑考虑再出一道题坑别人,防止被坑。

p.s:我们并不是直接对序列进行除以2的操作,而是知道了序列长度,我就能够通过除以2来知道当前GCD应

该要删掉多少个数之后才能变大,而变大之前,这个数是定值。

后话

样例其实很良心了,把需要特殊处理的1,2,3的情况都给出来了

\(n=2\)的情况,可以显然得出前一个数和后一个成1:2的关系

\(n=3\)的情况,例如\(2,4,6\)这个例子,我们先删除2,再删除4,然后删除6,可以显然得出是字典序最大的方案

也就是\(2,2,6\)\(now,now,now*3\)

那么我们每次把数列缩小到二分之一,递归处理,注意特判\(n=1,n=2,n=3\)的情况即可

代码

#include <bits/stdc++.h>
using namespace std;
void solve(int n, int now) {
    if (!n) {
        puts("");
        return;
    }
    if (n == 1) {
        printf("%d\n", now);
        return;
    }
    if (n == 2) {
        printf("%d %d\n", now, now * 2);
        return;
    }
    if (n == 3) {
        printf("%d %d %d\n", now, now, 3 * now);
        return;
    }
    for (int i = 1; i <= (n + 1) / 2; i++) printf("%d ", now);
    solve(n >> 1, now * 2);
}
int main() {
    while (1) {
        int n;
        scanf("%d", &n);
        if (!n)
            break;
        solve(n, 1);
    }
    return 0;
}
posted @ 2020-11-18 15:32  邦的轩辕  阅读(68)  评论(0编辑  收藏  举报