题目

题目描述

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

q 次修改,每次给定一个 x,若$$ a_{x}$$ 为 L,则将 $$a_{x}$$​ 修改成 R,否则将 $$a_{x}$$​ 修改成 L

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

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

输入格式

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

接下来 q 行,每行一个整数,表示本次修改的位置x

输出格式

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

输入输出样例

1
2
3
6 2
2
4
1
2
3
5
1
2
3
4
5
6
6 5
4
1
1
2
6
1
2
3
4
5
3
3
3
5
6

说明/提示

数据规模与约定

对于全部的测试点,保证 1≤n,q≤2×105,1 ≤ x ≤ n。

说明

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

思考

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

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

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#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