[题解]CF1884B Haunted House
思路
首先对于一个二进制数,如果它能被 \(2^i\) 整除,一定满足在此数中所有的 \(1\) 都在 \(i\) 或 \(i\) 的左边。
那么对于所有在 \(i\) 右边的 \(1\),都应该到 \(i\) 的左边。考虑用 vector 维护所有在 \(i\) 左边的 \(0\) 的位置。
显然对于所有的不合法的 \(1\),都会到 \(i\) 左边第 \(1\) 个 \(0\) 的位置,这个可以利用 lower_bound 实现。
令这个位置为 \(j\),那么对答案的贡献就是 \(j - i\)。
Code
#include <bits/stdc++.h>
#define re register
#define int long long
using namespace std;
int T,n;
string s;
inline void solve(){
int ans = 0;
vector<int> v;
cin >> n >> s;
reverse(s.begin(),s.end());
s = ' ' + s;
for (re int i = n;i;i--){
if (s[i] == '0') v.push_back(i);
}
for (re int i = 1;i <= n;i++){
if (s[i] == '0') cout << ans << " ";
else{
while (!v.empty() && v.back() <= i) v.pop_back();
if (v.empty()) cout << "-1 ";
else{
int id = v.back();
v.pop_back();
ans += id - i;
s[id] = '1';
cout << ans << " ";
}
}
}
cout << "\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号