一直过不了样例,AI也不管用,请各位DALAO救救我!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int, int>
#define VI vector<int>
#define sz(a) a.size()
#define all(a) a.begin(), a.end()
#define up(i, s, t) for (int i = s; i <= t; i++)
#define dw(i, s, t) for (int i = s; i >= t; i--)
struct BIT {
int n;
VI t;
void init(int x) { n = x, t.resize(x + 2); }
void add(int p, int d) { while (p <= n) t[p] += d, p += p & -p; }
int ask(int p) {
int res = 0;
while (p) res += t[p], p -= p & -p;
return res;
}
};
struct Type { int x, y, v, op, id; }; // 询问类型
const int N = 3e5 + 2, INF = 1e9;
int n, m, idx, res[N], state[N]; // state -> 当前状态
Type q[5 * N], tmp[5 * N]; // q存差分点集
BIT op_t, cdq_t; // 处理operate的BIT, 处理CDQ分治的BIT
set<int> s; // 便于快速查询左右第一个为0的点(影响区间 [L+1, p]~[p, R-1]
void Add(int x, int y, int v) { q[++idx] = {x, y, v, 0, 0}; }
void Add_sq(int x1, int y1, int x2, int y2, int d) {
Add(x2, y2, d);
if (x1 > 1) Add(x1 - 1, y2, -d);
if (y1 > 1) Add(x2, y1 - 1, -d);
if (x1 > 1 && y1 > 1) Add(x1 - 1, y1 - 1, d);
}
bool check(int l, int r) { return op_t.ask(r) - op_t.ask(l - 1) == r - l + 1; }
// check判断[l,r]是否全部是1
void work(int p, int t) { // 操作下标,操作轮数 目的:完成操作影响
if (!state[p]) {
auto it = s.upper_bound(p);
int L = *prev(it), R = *it;
s.insert(p);
Add_sq(L + 1, p, p, R - 1, -(m - t)); // 关灯,产生负贡献
} else {
s.erase(p);
auto it = s.upper_bound(p);
int L = *prev(it), R = *it;
Add_sq(L + 1, p, p, R - 1, m - t); // 开灯产生正贡献
}
}
void cdq(int l, int r) {
// CDQ分治,计算所有满足(t1 <= t2 && x1 >= x2 && y1 >= y2)的点对(x2, y2)的贡献
if (l >= r) return;
int mid = (l + r) >> 1, i = l, j = mid + 1, k = 0;
cdq(l, mid), cdq(mid + 1, r);
while (i <= mid || j <= r)
if (j > r || (i <= mid && q[i].x >= q[j].x)) {
if (!q[i].op) cdq_t.add(q[i].y, q[i].v);
tmp[++k] = q[i++];
} else {
if (q[j].op) res[q[j].id] += cdq_t.ask(n) - cdq_t.ask(q[j].y - 1);
tmp[++k] = q[j++];
}
up(i1, l, mid) if (!q[i1].op) cdq_t.add(q[i1].y, -q[i1].v);
for (int i1 = 1, j1 = l; i1 <= k; i1++, j1++) q[j1] = tmp[i1];
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
string ss;
cin >> n >> m >> ss, op_t.init(n + 2), cdq_t.init(n + 2);
up(i, 1, n) state[i] = ss[i - 1] - '0';
s.insert(0), s.insert(n + 1);
Add_sq(1, n, 1, n, m); // 先多算一部分,再减掉
up(i, 1, n) if (state[i]) op_t.add(i, 1);
up(i, 1, n) if (!state[i]) work(i, 0); // 计算
up(i, 1, m) {
cin >> ss;
if (ss[0] == 'q') {
int a, b; cin >> a >> b, b--;
if (check(a, b)) res[i] = -(m - i); // 先减掉多算的
q[++idx] = {a, b, 0, 1, i};
} else {
int x; cin >> x;
state[x] ^= 1, work(x, i),
res[i] = -INF;
if (state[x]) op_t.add(x, 1);
else op_t.add(x, -1);
}
}
cdq(1, idx);
up(i, 1, m) if (res[i] != -INF) cout << res[i] << '\n';
return 0;
}