专栏文章
题解:P13617 [ICPC 2024 APC] Bit Counting Sequence
P13617题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minqd83y
- 此快照首次捕获于
- 2025/12/02 06:38 3 个月前
- 此快照最后确认于
- 2025/12/02 06:38 3 个月前
思路
不难发现,其实 函数就是 ,虽然没有什么意义。楼下很多大佬都直接看出性质了,由于本人太菜,所以给一个特别中规中矩的方法。
与别的方法不同,这个方法从 数组最后往最前遍历。
最开始也就是在 的时候,最优答案一定是 。
对于 至 的情况,有几种可能:
- 如果 为 ,上一位答案为 则可以减,否则无解。
- 如果 ,显然无解。因为发生进位 的个数是不增的,而不发生进位 的个数只能加 。
- 如果 ,答案的最低二进制位一定为 ,我们直接看答案能不能减 即可。
- 如果 ,一定发生了进位,且进位之后答案末尾只有 个 。我们只需在答案最末尾补齐 然后看能不能减 即可。
最后非常重要的:从头到位扫一遍,看看可不可以满足整个序列。
引用机房神犇 gaozeju 的话讲:检查满不满足原因就是假定序列是合法的,但是序列有可能不合法。
代码
CPP#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N(5e5+5);
int T,n,a[N];
ll ans;
inline int getpos(ll x){
for(int d(0);x;){
if(x&1)return d;
x>>=1;
++d;
}return -1;
}
inline int cnt(ll x){
int res(0);
for(;x;x>>=1){
if(x&1)++res;
}return res;
}
inline void solve(){
cin>>n;
for(int i(1);i<=n;++i)cin>>a[i];
ans=1;ans<<=a[n];--ans;
for(int i(n-1);i>=1;--i){
if(a[i]==0){
if(ans==1)--ans;
else{cout<<-1<<'\n';return ;}
}else if(a[i+1]-a[i]>1){cout<<-1<<'\n';return ;}
else if(a[i+1]-a[i]==1){
if(ans>=1)--ans;
else{cout<<-1<<'\n';return ;}
}else{
int pos=getpos(ans),chg=a[i]-a[i+1]+1;
if(pos==-1){cout<<-1<<'\n';return ;}
if(pos>chg){cout<<-1<<'\n';return ;}
ans<<=(chg-pos);
if(ans-1>=0)--ans;
else{cout<<-1<<'\n';return ;}
}
}ll tmp=ans;
for(int i(1);i<=n;++i){
if(cnt(tmp)==a[i])++tmp;
else{cout<<-1<<'\n';return ;}
}cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>T;
for(;T;--T)solve();
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...