一直在想他会不会一直合并下去,然后想用优先队列或者set什么的维护一下动态序列,结果发现有个重要的性质没考虑到。
考虑一个数字,他要变得更大,那就合成。合成后变为奇数。此时能与这个奇数合成的只有偶数,而一个数字合成后必定成为奇数。
这也就是说我们每次合成,其中一个数字必定来自于原始序列,即未经过合成操作的。所以每次操作枚举一下原始序列即可,贪心地从大到小枚举,递归一下。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define int long long
#define endl '\n'
#define P pair<int,int>
#define lson node << 1
#define rson node << 1 | 1
inline int lowbit(int x) {return -x & x;}
const int maxn = 2e5 + 5;
int a[maxn];
map<int,int> mp,mp2;
int n;
bool check(int x){
if (mp[x]){
mp[x] --;
mp2[x] ++;
return true;
}
if ((x % 2 == 0) || (x == 1)) return false;
return check(x / 2) && check(x / 2 + 1);
}
void solve(){
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
mp[a[i]] ++;
}
sort(a + 1,a + 1 + n,greater<int>());
for (int i = 1; i <= n; ++i) {
if (!mp[a[i]]) continue;
mp[a[i]] --;
mp2.clear();
if (check(a[i] + 1)){
mp[a[i] + a[i] + 1] ++;
continue;
}
else{
for(auto k : mp2){
mp[k.first] += k.second;
}
}
mp2.clear();
if (check(a[i] - 1)){
mp[a[i] + a[i] - 1] ++;
continue;
}
else{
for(auto k : mp2){
mp[k.first] += k.second;
}
}
mp[a[i]] ++;
}
vector<int> res;
for(auto k : mp){
if (k.second && k.first){
for (int i = 1; i <= k.second; ++i) {
res.push_back(k.first);
}
}
}
cout << res.size() << endl;
for(auto k : res) cout << k << ' ';
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T = 1;
// cin >> T;
while (T--) solve();
}