[题解]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;
}
posted @ 2025-11-06 20:21  Sinktank  阅读(10)  评论(0)    收藏  举报
★CLICK FOR MORE INFO★ TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2025 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.