Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2)C. Divisor Chain

C. Divisor Chain
题意:给定一个n,每次可以对n进行的操作是将n减去n的因子,现在希望将n变为1,并且所有减去的因子不能出现超过两次,让我们构造一个操作序列。
看了题解才明白,题目的限制就是每个因子出现的次数我能超过两次,如果能想到二进制这道题就解决了,我们知道2^k每次都减去 其一半这样减到1每个因子只会出现一次,如果我们能先将n转换成最大的2^k的话并且保证这个转化的过程也不会出现使因子出现两次的情况就可以解决了,我们怎么才能将n转化为一个2的整次幂呢?这时我们考虑n的二进制,例如n为14,其二进制为1110我们每次减去他的lowbit(),lowbit()也是n的因子并且在这个过程每个因子至多会出现一次,这样两个过程就可以保证每个因子出现的次数最多为2。
能清楚这个思路代码就很简单了。

#include <bits/stdc++.h>
#define LL long long
 
using namespace std;
const int N = 2e5 + 10;
int t;
LL lowbit(LL x)
{
	return x & (-x);
}
void solve()
{
	LL n; scanf("%lld", &n);
	vector<LL>ans;
	ans.push_back(n);
	while(n != lowbit(n))
	{
		n -= lowbit(n);
		ans.push_back(n);
	}
	while(n != 1)
	{
		n = n >> 1;
		ans.push_back(n);
	}
	cout << ans.size() << endl;
	for(auto x : ans)	cout << x << ' ';
	puts("");
}

int main()
{
//	freopen("1.in", "r", stdin);
	scanf("%d", &t);
	while(t --)	solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值