[题解]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;
}
浙公网安备 33010602011771号