[题解]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;  
}  
posted @ 2024-06-25 12:29  WBIKPS  阅读(18)  评论(0)    收藏  举报