首页 > 代码库 > Vijos P1881 闪烁的繁星 (自己加强了一下。。)

Vijos P1881 闪烁的繁星 (自己加强了一下。。)

如果每一次查询的不是整个长度,而是[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;
}

Vijos P1881 闪烁的繁星 (自己加强了一下。。)