样例1的输出我是3 3 6 4.重点检查下op==2时二分部分。另外两个操作应该都没错
#include<bits/stdc++.h>
#define ll long long
#define lc x<<1
#define rc x<<1|1
using namespace std;
const ll N = 2e5+100;
struct node {
ll l, r, val;
ll lazy_set;
bool is_set;
ll lmx, rmx, mx;
} tr[N << 2];
ll n, m;
void pushup(ll x) {
tr[x].val = tr[lc].val + tr[rc].val;
tr[x].lmx = (tr[lc].lmx == tr[lc].r - tr[lc].l + 1) ? (tr[lc].lmx + tr[rc].lmx) : tr[lc].lmx;
tr[x].rmx = (tr[rc].rmx == tr[rc].r - tr[rc].l + 1) ? (tr[rc].rmx + tr[lc].rmx) : tr[rc].rmx;
tr[x].mx = max(tr[lc].rmx + tr[rc].lmx, max(tr[lc].mx, tr[rc].mx));
return;
}
void pushdown(ll x) {
if (tr[x].is_set) {
tr[lc].val = tr[x].lazy_set * (tr[lc].r - tr[lc].l + 1);
tr[rc].val = tr[x].lazy_set * (tr[rc].r - tr[rc].l + 1);
tr[lc].lmx = tr[lc].rmx = tr[lc].mx = (1 - tr[x].lazy_set) * (tr[lc].r - tr[lc].l + 1);
tr[rc].lmx = tr[rc].rmx = tr[rc].mx = (1 - tr[x].lazy_set) * (tr[rc].r - tr[rc].l + 1);
tr[lc].lazy_set = tr[rc].lazy_set = tr[x].lazy_set;
tr[lc].is_set = tr[rc].is_set = 1;
tr[x].is_set = 0;
}
return;
}
void build(ll x, ll l, ll r) {
tr[x].l = l;
tr[x].r = r;
if (l == r) {
tr[x].val = 1;
tr[x].rmx = tr[x].lmx = tr[x].mx = 0;
return;
}
ll m = (l + r) >> 1;
build(lc, l, m);
build(rc, m + 1, r);
pushup(x);
return;
}
void change_set(ll x, ll l, ll r, ll k) {
if (l <= tr[x].l && tr[x].r <= r) {
tr[x].val = k * (tr[x].r - tr[x].l + 1);
tr[x].lmx = tr[x].rmx = tr[x].mx = (1 - k) * (tr[x].r - tr[x].l + 1);
tr[x].lazy_set = k;
tr[x].is_set = 1;
return;
}
pushdown(x);
ll m = (tr[x].l + tr[x].r) >> 1;
if (l <= m) change_set(lc, l, r, k);
if (r > m) change_set(rc, l, r, k);
pushup(x);
return;
}
node fin_max(ll x, ll l, ll r) {
if (l <= tr[x].l && tr[x].r <= r) return tr[x];
pushdown(x);
ll m = (tr[x].l + tr[x].r) >> 1;
if (r <= m) return fin_max(lc, l, r);
if (l > m) return fin_max(rc, l, r);
node left = fin_max(lc, l, r), right = fin_max(rc, l, r), res;
res.val = left.val + right.val;
res.lmx = (left.lmx == left.r - left.l + 1) ? (left.lmx + right.lmx) : left.lmx;
res.rmx = (right.rmx == right.r - right.l + 1) ? (right.rmx + left.rmx) : right.rmx;
res.mx = max(left.rmx + right.lmx, max(left.mx, right.mx));
return res;
}
ll fin_sum(ll x, ll l, ll r) {
if (l <= tr[x].l && tr[x].r <= r) return tr[x].val;
pushdown(x);
ll m = (tr[x].l + tr[x].r) >> 1, sum = 0;
if (l <= m) sum += fin_sum(lc, l, r);
if (r > m) sum += fin_sum(rc, l, r);
return sum;
}
int main() {
cin >> n >> m;
build(1, 1, n);
for (ll i = 1; i <= m; i++) {
ll op;
cin >> op;
if (op == 0) {
ll l, r;
cin >> l >> r;
change_set(1, l, r, 0);
} else if (op == 1) {
ll from_l, from_r, to_l, to_r;
cin >> from_l >> from_r >> to_l >> to_r;
ll from_sum = fin_sum(1, from_l, from_r), to_sum = fin_sum(1, to_l, to_r);
cout << "<<<" << from_sum << " " << to_sum << "\n";
change_set(1, from_l, from_r, 0);
if (to_sum < to_r - to_l + 1 && from_sum != 0) {
if (from_sum >= to_r - to_l + 1 - to_sum) change_set(1, to_l, to_r, 1);
else {
ll l = to_l, r = to_r, mid;
while (l <= r) {
mid = (l + r) >> 1;
ll k = mid - l + 1 - fin_sum(1, to_l, mid);
cout << "<<<" << k << "\n";
if (k == from_sum) break;
else if (k < from_sum) l = mid+1;
else r = mid;
}
change_set(1, to_l, mid, 1);
}
}
} else if (op == 2) {
ll l, r;
cin >> l >> r;
cout << fin_max(1, l, r).mx << "\n";
}
}
}