cf 1263E. Editor
Problem Description
传送门
题意
给你一段序列,其中L
代表左移,R
代表右移,小写字母
代表在当前位置放置对应字母,)
,(
代表在当前位置放置左右括号,当括号可以匹配时输出括号的最大层数,否则输出-1
题解
- 小写字母是无意义的操作
- 当
(
时我们在序列当前位置加1,)
我们在当前位置减1。如此最大层数就是序列前缀和的最大值,括号能否匹配取决于前缀和最小的是否等于0以及总共的左右括号数是否相等 - 线段树区间修改,区间最值
C++
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
#define ll long long
const int N = 1e6 + 50;
char a[N];
ll maxn[4 * N], sum[4 * N], minn[4 * N], sumf[4 * N], tag[4 * N];
int n, q, z;
int cnt;
void pushup(int o, int l, int r)
{
int lo = 2 * o, ro = 2 * o + 1, m = (l + r) >> 1;
sum[o] = sum[lo] + sum[ro];
maxn[o] = max(maxn[lo], maxn[ro]);
minn[o] = min(minn[lo], minn[ro]);
sumf[o] = sumf[lo] + sumf[ro];
}
void build(int o, int l, int r)
{
if (l == r)
{
sum[o] = maxn[o] = minn[o] = 0;
sumf[o] = 0;
return;
}
int lo = 2 * o, ro = 2 * o + 1, m = (l + r) >> 1;
build(lo, l, m);
build(ro, m + 1, r);
pushup(o, l, r);
}
void pushdown(int o, int l, int r)
{
if (l == r)
return;
int lo = 2 * o, ro = 2 * o + 1, m = (l + r) >> 1;
if (tag[o])
{
tag[lo] += tag[o];
tag[ro] += tag[o];
sumf[lo] += (ll)(m - l + 1) * tag[o] * tag[o] + (ll)2 * tag[o] * sum[lo];
sumf[ro] += (ll)(r - m) * tag[o] * tag[o] + (ll)2 * tag[o] * sum[ro];
sum[lo] += (ll)(m - l + 1) * tag[o];
sum[ro] += (ll)(r - m) * tag[o];
maxn[lo] += tag[o];
maxn[ro] += tag[o];
minn[lo] += tag[o];
minn[ro] += tag[o];
}
tag[o] = 0;
}
int addl, addr, addi;
void add(int o, int l, int r)
{
if (l >= addl && r <= addr)
{
sumf[o] += (ll)(r - l + 1) * addi * addi + 2ll * addi * sum[o];
sum[o] += (ll)(r - l + 1) * addi;
maxn[o] += addi;
minn[o] += addi;
tag[o] += addi;
return;
}
pushdown(o, l, r);
int lo = 2 * o, ro = 2 * o + 1, m = (l + r) >> 1;
if (addl <= m)
add(lo, l, m);
if (addr > m)
add(ro, m + 1, r);
pushup(o, l, r);
}
ll qsum = 0, qsumf = 0;
int ql, qr;
void query(int o, int l, int r)
{
if (l >= ql && r <= qr)
{
qsum += sum[o];
qsumf += sumf[o];
return;
}
int lo = 2 * o, ro = 2 * o + 1, m = (l + r) >> 1;
pushdown(o, l, r);
if (ql <= m)
query(lo, l, m);
if (qr > m)
query(ro, m + 1, r);
pushup(o, l, r);
}
string s;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("r.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin >> n >> s;
build(1, 1, n);
for (int i = 1; i <= n; i++)
a[i] = 'a';
cin >> n >> s;
int now = 1;
for (int i = 0; i < n; i++)
{
if (s[i] == 'L')
{
now--;
now = max(now, 1);
}
else if (s[i] == 'R')
{
now++;
}
else
{
addl = now;
addr = n;
if (a[now] == '(')
{
if (s[i] == '(')
addi = 0;
else if (s[i] == ')')
addi = -2;
else
addi = -1;
}
else if (a[now] == ')')
{
if (s[i] == ')')
addi = 0;
else if (s[i] == '(')
addi = 2;
else
addi = 1;
}
else
{
if (s[i] == '(')
addi = 1;
else if (s[i] == ')')
addi = -1;
else
addi = 0;
}
add(1, 1, n);
cnt += addi;
a[now] = s[i];
}
#ifdef debug
cout << maxn[1] << " " << minn[1] << endl;
#else
if (cnt == 0 and minn[1] == 0)
cout << maxn[1] << " ";
else
cout << -1 << " ";
#endif
}
}