编辑
2025-09-01
刷题
00

https://www.nowcoder.com/practice/3647d44e120b4ec19536a8236d251a06?tpId=182&tqId=46507&rp=1&sourceUrl=%2Fexam%2Foj%3FquestionJobId%3D10%26subTabName%3Donline_coding_page&difficulty=undefined&judgeStatus=undefined&tags=&title=

#include <bits/stdc++.h> using namespace std; #define endl '\n' #define int long long const int M = 3e5 + 5, mod = 998244353; int a[M]; struct dian { int l, r, lw, rw, sum; // lw表示左边连续的1的个数 // rw表示右边连续的1的个数 // sum表示区间每段连续1除2向上取整的和 } f[M << 2]; dian merge(dian x, dian y) { int c1 = x.lw, c2 = x.rw; int c3 = y.lw, c4 = y.rw; int flag1 = 0, flag2 = 0; if (c1 == x.r - x.l + 1) flag1 = 1; if (c3 == y.r - y.l + 1) flag2 = 1; int id = 0; dian ans; ans.l = x.l; ans.r = y.r; // 如果左子树全为1,右子树不为1,则将左边连续的1的个数加到右子树的左边 if (flag1 == 1 && flag2 == 0) { ans.lw = c1 + c3; ans.rw = c4; ans.sum = (c1 + c3 + 1) / 2 - (c3 + 1) / 2 + y.sum; return ans; } if (flag1 == 0 && flag2 == 1) { ans.lw = c1; ans.rw = c2 + c4; ans.sum = (c2 + c4 + 1) / 2 - (c2 + 1) / 2 + x.sum; return ans; } if (flag1 == 0 && flag2 == 0) { ans.lw = c1; ans.rw = c4; ans.sum = x.sum + y.sum - (c2 + 1) / 2 - (c3 + 1) / 2 + (c2 + c3 + 1) / 2; return ans; } ans.lw = c1 + c3; ans.rw = c2 + c4; ans.sum = (c1 + c3 + 1) / 2; return ans; } void pushup(int id) { f[id] = merge(f[id << 1], f[id << 1 | 1]); } void build(int id, int l, int r) { f[id].l = l, f[id].r = r; if (l == r) { f[id].lw = f[id].rw = a[l]; f[id].sum = a[l]; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); pushup(id); } dian query(int id, int l, int r) { if (l <= f[id].l && f[id].r <= r) return f[id]; int mid = (f[id].l + f[id].r) >> 1; if (r <= mid) return query(id << 1, l, r); if (l > mid) return query(id << 1 | 1, l, r); dian x = query(id << 1, l, r); dian y = query(id << 1 | 1, l, r); return merge(x, y); } void solve() { int n, q; cin >> n >> q; string s; cin >> s; vector<int> sum(n + 2); for (int i = 1; i <= n; i++) { a[i] = s[i - 1] - '0'; sum[i] = sum[i - 1] + (a[i] == 0); } build(1, 1, n); while (q--) { int l, r; cin >> l >> r; dian ans = query(1, l, r); cout << ans.sum + (sum[r] - sum[l - 1]) << endl; } } signed main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int t = 1; // cin >> t; while (t--) solve(); return 0; }
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay