如果每一次查询的不是整个长度,而是[x, y]这个区间。。闲来无事自己写了一下,感觉是对的,这样就变成了合并区间。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#include <algorithm>
#define mem(f) memset(f,0,sizeof(f))
#define M 100005
#define mod 1000000007
#define lson o<<1, l, m
#define rson o<<1|1, m+1, r
using namespace std;
typedef long long LL;
const int MAX = 0x3f3f3f3f;
const int maxn = 200005;
int mx_three(int a, int b, int c) {
return max(a, max(b, c));
}
int n, q, c, x, y, b[maxn];
struct C {
int mx, lx, rx;
} a[maxn<<2];
void build(int o, int l, int r) {
a[o].lx = a[o].mx = a[o].rx = 1;
if(l == r) return;
int m = (l+r) >> 1;
build(lson);
build(rson);
}
C query(int o, int l, int r) {
if(x <= l && r <= y) return a[o];
int m = (l+r) >> 1, len = r-l+1;
if(y <= m) return query(lson);
if(m < x ) return query(rson);
C s, s1, s2;
s1 = query(lson);
s2 = query(rson);
s.lx = s1.lx;
s.rx = s2.rx;
if(b[m] != b[m+1]) {
if(s.lx == len-(len>>1)) s.lx += s2.lx;
if(s.rx == len>>1) s.rx += s1.rx;
s.mx = mx_three(s1.mx, s2.mx, s1.rx+s2.lx);
} else s.mx = max(s1.mx, s2.mx);
return s;
}
void update(int o, int l, int r) {
if(l == r) {
b[c] ^= 1;
return;
}
int m = (l+r) >> 1;
if(c <= m) update(lson);
else update(rson);
int len = r-l+1, L = o<<1, R = o<<1|1;
a[o].lx = a[L].lx;
a[o].rx = a[R].rx;
if(b[m] != b[m+1]) {
a[o].mx = mx_three(a[L].mx, a[R].mx, a[L].rx+a[R].lx);
if(a[o].lx == len-(len>>1)) a[o].lx += a[R].lx;
if(a[o].rx == len>>1) a[o].rx += a[L].rx;
} else a[o].mx = max(a[L].mx, a[R].mx);
}
int main()
{
scanf("%d%d", &n, &q);
build(1, 1, n);
while(q--) {
int rr;
scanf("%d", &rr);
if(rr == 2) {
scanf("%d", &c);
update(1, 1, n);
} else {
scanf("%d%d", &x, &y);
printf("%d\n", query(1, 1, n).mx);
}
}
return 0;
}