如果每一次查詢的不是整個長度,而是[x, y]這個區間。。閒來無事自己寫了一下,感覺是對的,這樣就變成了合並區間。
#include#include #include #include #include #include #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; }