[P6492] [COCI2010-2011#6] STEP(线段树区间合并)

【原题】

题目描述

给定一个长度为 \(n\) 的字符序列 \(a\),初始时序列中全部都是字符 L

\(q\)次修改,每次给定一个 \(x\),若 \(a_x\)L,则将 \(a_x\)修改成 R,否则将 \(a_x\) 修改成 L

对于一个只含字符 LR 的字符串 \(s\),若其中不存在连续的 LR,则称 \(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 '\n'
#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;
	}
	
}
posted @ 2020-08-06 20:10  kurum!  阅读(166)  评论(0编辑  收藏  举报