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;
}