【原题】
题目描述
给定一个长度为 (n) 的字符序列 (a),初始时序列中全部都是字符 L
。
有 (q)次修改,每次给定一个 (x),若 (a_x) 为 L
,则将 (a_x)修改成 R
,否则将 (a_x) 修改成 L
。
对于一个只含字符 L
,R
的字符串 (s),若其中不存在连续的 L
和 R
,则称 (s) 满足要求。
每次修改后,请输出当前序列 (a) 中最长的满足要求的连续子串的长度。
输入格式
第一行有两个整数,分别表示序列的长度 (n) 和修改操作的次数 (q)。
接下来(q)行,每行一个整数,表示本次修改的位置 (x)。
输出格式
对于每次修改操作,输出一行一个整数表示修改(a) 中最长的满足要求的子串的长度。
输入输出样例
输入 #1
6 2
2
4
输出 #1
3
5
输入 #2
6 5
4
1
1
2
6
输出 #2
3
3
3
5
6
说明/提示
数据规模与约定
对于全部的测试点,保证 (1≤n,q≤2×10^5,1≤x≤n)。
说明
题目译自 COCI2010-2011 CONTEST #6 *T5 STEP*,翻译来自 @一扶苏一。
【思路】区间合并裸题
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#define LL long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f
#define PI 3.1415926535898
#define F first
#define S second
#define endl '
'
#define lson rt << 1
#define rson rt << 1 | 1
#define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int maxn = 2e5 + 7;
const int maxm = 2e5 + 7;
const int mod = 1e9 + 7;
int n, m;
struct node
{
int l, r, mxlen, llen, rlen, len;
}t[maxn * 4];
void push_up(int rt)
{
t[rt].mxlen = max(t[lson].mxlen, t[rson].mxlen);
t[rt].l = t[lson].l;
t[rt].r = t[rson].r;
t[rt].llen = t[lson].llen;
t[rt].rlen = t[rson].rlen;
if (t[lson].llen == t[lson].len && t[lson].r != t[rson].l)
{
t[rt].llen += t[rson].llen;
t[rt].mxlen = max(t[rt].mxlen, t[rt].llen);
}
if (t[rson].rlen == t[rson].len && t[rson].l != t[lson].r)
{
t[rt].rlen += t[lson].rlen;
t[rt].mxlen = max(t[rt].mxlen, t[rt].rlen);
}
if (t[lson].r != t[rson].l) t[rt].mxlen = max(t[rt].mxlen, t[lson].rlen + t[rson].llen);
return;
}
void build(int rt, int l, int r)
{
if (l == r)
{
t[rt].len = t[rt].mxlen = t[rt].llen = t[rt].rlen = 1;
return;
}
int mid = (l + r) / 2;
build(lson, l, mid);
build(rson, mid + 1, r);
t[rt].len = t[lson].len + t[rson].len;
push_up(rt);
return;
}
void update(int rt, int index, int L, int R)
{
if (L == R)
{
t[rt].l = t[rt].r = 1 - t[rt].l;
return;
}
int mid = (L + R) / 2;
if (index <= mid) update(lson, index, L, mid);
else update(rson, index, mid + 1, R);
push_up(rt);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
build(1, 1, n);
int x;
_rep(i, 1, m)
{
cin >> x;
update(1, x, 1, n);
cout << t[1].mxlen << endl;
}
}