Sequence Transformation CodeForces - 1059C

题目

在这里插入图片描述
在这里插入图片描述

思路

首先有一个显而易见的结论:对于任意排列,b序列中的前n/2个数总是1。
原因是相邻的两个数互质。
现在我们来考虑一个长度大于3的排列,怎样才能将b序列的字典序最大。
根据字典序的定义,我们需要最大化每一次进入队列的gcd。
即,当前最大就是整体最好的选择。
那么我们对于任意两个相邻的数,都有一个选择:删除其中的奇数或删除其中的偶数。
我们应该全部删除奇数或者全部删除偶数,不然就会有两个数相邻,从而出现gcd=1使得答案不优。
如果我们删除偶数,我们就会发现有ai=1使得这个序列的gcd=1而使得答案不优。
所以我们对于每个序列,都要删除奇数,使得gcd*=2。
观察操作后的序列
    a{2,4,...,(n&1)?(n-1):(n)}
我们可以将它看成
    a{2*1,2*2,2*3,...,2*(n/2)}
这样我们就把问题转化成了一个长度为n/2的子问题。
对于1<=n<=3的序列或长度小于等于3的子问题,题目的样例就是我们想要的结果,特判即可。

代码

#include <iostream>

using namespace std;

int main() {
	int n;
	cin >> n;
	int m = 1;
	while (n > 3) {
		for (int i = 0; i < (n + 1) / 2; i++) {
			cout << m << " ";
		}
		n = n / 2;
		m = m * 2;
	}
	if (n == 3) {
		cout << m << " " << m << " " << 3 * m;
	}
	else if (n == 2) {
		cout << m << " " << 2 * m;
	}
	else cout << m;

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值