首页 > 代码库 > Vijos P1881 闪烁的繁星

Vijos P1881 闪烁的繁星

背景

繁星闪烁着--深蓝的太空
何曾听得见他们对语
沉默中
微光里
他们深深的互相颂赞了

描述

繁星, 漫天的繁星.
繁星排成一列, 我数一数呀, 一共有N只小星星呢.

星星们是听话的好孩子, 小岛在指挥它们跳舞呢.
舞蹈开始前, 它们都亮了起来!

小岛指一指第i只小星星, 只见第i只小星星立刻改变了自己的状态.
如果它之前是亮着的, 那么立刻就灭掉了.
如果它之前是灭掉的, 现在就立刻亮了呀!

如果说, 可以有连续若干只小星星.
其中任意相邻两只星星状态不同.
那就是最美的了.

小岛希望知道:
每一次发出指令之后
能找到最长的连续小星星, 满足上述需求的
有多长?

格式

输入格式

第一行有两个整数, 分别为星星总数N, 和指令总数Q.
1<=N<=200,000; 1<=Q<=200,000.
之后Q行, 每行有一个整数i: 1<=i<=N, 表示小岛发出的指令.

输出格式

输出有Q行, 其中每i行有一个整数.
表示小岛的第i条指令发出之后, 可以找到的满足要求的最长连续星星序列有多长?

样例1

样例输入1[复制]

6 2
2
4

样例输出1[复制]

3
5

限制

对于20%的数据: N, Q <= 100.
对于30%的数据: N, Q <= 70000.
对于100%的数据: 1 <= N, Q <= 200,000.

提示

对于样例, 星星序列的状态依次为: OOOOOO -> OXOOOO -> OXOXOO
这里用O表示亮着的星星, 用X表示灭掉的星星.


线段树维护每段区间里的从左边第一个往右能延伸的最大长度,从右边最后一个往左能延伸的最大长度,还有中间的最大长度。

#include <stdio.h>
#include <string.h>
#include <math.h>
#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, 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);
}

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--) {
        scanf("%d", &c);
        update(1, 1, n);
        printf("%d\n", a[1].mx);
    }
    return 0;
}




Vijos P1881 闪烁的繁星