洛谷 P6492 [COCI20102011#6] STEP

题目

题目描述

给定一个长度为 nn 的字符序列 aa,初始时序列中全部都是字符 L

有 qq 次修改,每次给定一个 xx,若 a_xax 为 L,则将 a_xax 修改成 R,否则将 a_xax 修改成 L

对于一个只含字符 LR 的字符串 ss,若其中不存在连续的 L 和 R,则称 ss 满足要求。

每次修改后,请输出当前序列 aa 中最长的满足要求的连续子串的长度。

输入格式

第一行有两个整数,分别表示序列的长度 nn 和修改操作的次数 qq。

接下来 qq 行,每行一个整数,表示本次修改的位置 xx。

输出格式

对于每次修改操作,输出一行一个整数表示修改 aa 中最长的满足要求的子串的长度。

输入输出样例

输入 #1
6 2
2
4
输出 #1
3
5
输入 #2
6 5
4
1
1
2
6
输出 #2
3
3
3
5
6

说明/提示

数据规模与约定

对于全部的测试点,保证 1n,q2×1051 ≤ x ≤ n

说明

题目译自 COCI2010-2011 CONTEST #6 T5 STEP,翻译来自 @一扶苏一

思考

这个题其实和区间和区别并不大,只是把求和的push_up操作改为求最长的连续符合条件的串即可。

分左,中,右三部分考虑。

代码

#include <bits/stdc++.h>

using namespace std;

inline long long read()
{
    long long x = 0;
    int f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
void write(const int& x)
{
    if (!x)
    {
        putchar('0');
        return;
    }
    char f[100];
    int tmp = x;
    if (tmp < 0)
    {
        tmp = -tmp;
        putchar('-');
    }
    int s = 0;
    while (tmp > 0)
    {
        f[s++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while (s > 0)
    {
        putchar(f[--s]);
    }
}

const int MAXN = 1000090;

bool nums[MAXN];
long long totN;
long long totDO;

struct Node
{
    long long lvalue;
    long long rvalue;
    long long midvalue;
    long long l, r;
    Node* lch, * rch;
    inline void push_up()
    {
        lvalue=lch->lvalue;
        rvalue=rch->rvalue;
        if (nums[lch->r]!=nums[rch->l])
        {
            if (lch->lvalue==(lch->r-lch->l+1))
            {
                lvalue+=rch->lvalue;
            }
            if (rch->rvalue==(rch->r-rch->l+1))
            {
                rvalue+=lch->rvalue;
            }
        }
        midvalue=max(nums[lch->r]!=nums[rch->l]?lch->rvalue+rch->lvalue:0,max(lch->midvalue,rch->midvalue));
    }
    Node(const long long L, const long long R)
    {
        l = L;
        r = R;
        if (l==r)
        {
            lch = NULL;
            rch = NULL;
            lvalue=rvalue=midvalue=1;
        }
        else
        {
            long long mid = (l + r) >> 1;
            lch = new Node(L, mid);
            rch = new Node(mid + 1, R);
            push_up();
        }
    }
    inline void update(const long long w)
    {
        if (l==r)
        {
            return;
        }
        if (lch->r>=w)
        {
            lch->update(w);
        } else
        {
            rch->update(w);
        }
        push_up();
    }
};

int main()
{
    totN=read();
    totDO=read();
    Node *root=new Node(1,totN);
    for (int i = 1; i <= totDO; ++i)
    {
        auto tempX=read();
        nums[tempX]^=1;
        root->update(tempX);
        write(root->midvalue);
        putchar('\n');
    }
    return 0;
}//LikiBlaze Code
原文地址:https://www.cnblogs.com/genshin/p/13246597.html