[题解]P12025 [USACO25OPEN] Sequence Construction S

[题解]P12025 [USACO25OPEN] Sequence Construction S

P12025 [USACO25OPEN] Sequence Construction S

Ref:P12025 [USACO25OPEN] Sequence Construction S 题解 - Little_x_starTYJ

我们的构造要满足三个条件:

  • \(1\le N\le 100\)
  • \(\sum_i^N A_i=M\)
  • \(\bigoplus_i^N \text{popcount}(i)=K\)

异或和的条件不是很好看,考虑先解决它。

考虑紧贴下界(最小化和)进行构造,只需依次取出 \(K\) 的每个 lowbit \(x\),将 \(2^x-1\) 加入答案即可。

记此时的和还差 \(M'\)\(M\)

我们分类讨论一下:

  • \(M'<0\):最小化和的情况下仍不合法,所以无解。

  • \(M'=0\):已经合法。

  • \(M'=1\)

    • 若当前方案中存在 \(1\),则将这个 \(1\) 变成 \(2\)
    • 若当前方案中不存在 \(1\),则无解。
  • \(M'>1\)\(M'\) 为偶数:补两个 \(\dfrac{M'}{2}\)

  • \(M'>1\)\(M'\) 为奇数:先补 \(1,2\),再补两个 \(\dfrac{M'}{2}\)

这样构造序列长度的上界大概是 \(5+4=9\)

点击查看代码
#include<bits/stdc++.h>
#define eb emplace_back
using namespace std;
int t,m,k;
vector<int> ans;
inline int lb(int x){return x&-x;}
inline void output(){cout<<ans.size()<<"\n";for(int i:ans) cout<<i<<" ";cout<<"\n";
}
signed main(){cin>>t;while(t--){ans.clear();cin>>m>>k;for(int i=k;i;i-=lb(i)){int t=(1<<lb(i))-1;ans.eb(t);m-=t;}if(m<0) cout<<"-1\n";else if(m==0){output();}else if(m==1){bool flg=0;for(int& i:ans) if(i==1){i=2,flg=1;break;}if(flg) output();else cout<<"-1\n";}else if(m&1){ans.eb(1),ans.eb(2);m-=3;if(m) ans.eb(m/2),ans.eb(m/2);output();}else{ans.eb(m/2),ans.eb(m/2);output();}}return 0;
}