题目链接:https://codeforces.com/contest/1263/problem/E
题意:一个编译器,每次输入一些字符,R表示光标右移,L表示光标左移,然后有一些左括号( 和 右括号 ),每次会询问当前输入的数据的括号是否合法,如果不合法输出-1,如果合法输出最大合法的括号对数,合法的括号就是()这种形式的。
思路:大致思路是用线段树维护区间一个区间前缀和,初始化前缀和为0。遇到单点更新,(让管辖区间+1,)就让管辖区间-1,,判断是否是合法括号需要判断区间最小值是否为0,且保证1到n区间的前缀和为0(画图思考一下),满足两种条件的同时才能说明此为合法括号序列,最终查询区间最大值就是最大匹配的括号对数(画图思考)。
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
struct node{
int l,r;
int Min,Max;
int val;
int lazy;
}tree[maxn*4+5];
void pushdown(int index){
if(tree[index].lazy){
tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
tree[index<<1].Max += tree[index].lazy;
tree[index<<1|1].Max += tree[index].lazy;
tree[index<<1].Min += tree[index].lazy;
tree[index<<1|1].Min += tree[index].lazy;
tree[index<<1].lazy += tree[index].lazy;
tree[index<<1|1].lazy += tree[index].lazy;
tree[index].lazy = 0;
}
}
void pushup(int index){
tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}
void build(int l,int r,int index){//建树
tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
if(l == r){
//scanf("%d",&tree[index].val);
tree[index].val = 0;
tree[index].Max = tree[index].Min = tree[index].val;
return;
}
int mid = (l+r)>>1;//
build(l,mid,index<<1);
build(mid+1,r,index<<1|1);
pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
if(l <= tree[index].l && r >= tree[index].r){
tree[index].val += (tree[index].r-tree[index].l+1)*val;
tree[index].Max += val;
tree[index].Min += val;
tree[index].lazy += val;//延时标记
return ;
}
pushdown(index);
int mid = (tree[index].l+tree[index].r)>>1;
if(l <= mid){
update(l,r,index<<1,val);
}
if(r > mid){
update(l,r,index<<1|1,val);
}
pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
if(l <= tree[index].l && r >= tree[index].r){
return tree[index].val;
//return tree[index].mn;
}
pushdown(index);
int mid = (tree[index].l+tree[index].r)>>1;
LL res = 0;
LL Max = 0;
LL Min = inf;
if(l <= mid){
res += query_range(l,r,index<<1);
}
if(r > mid){
res += query_range(l,r,index<<1|1);
}
return res;
}
LL query_max(int l,int r,int index){//最大值查询
if(l<= tree[index].l && r>= tree[index].r ){
return tree[index].Max;
}
pushdown(index);
int mid = (tree[index].l + tree[index].r )>>1;
LL ans = 0;
LL MAX = 0,MIN = inf;
if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
if(l<= tree[index].l && r>= tree[index].r ){
return tree[index].Min;
}
pushdown(index);
int mid = (tree[index].l + tree[index].r )>>1;
LL ans = 0;
LL MAX = 0,MIN = inf;
if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
return MIN;
}
string s;
LL ss[maxn];
int main(){
int n;
scanf("%d",&n);
n = n+10;
build(1,n,1);
cin>>s;
int pos = 1;
vector ans;
for(int i = 0;i1) pos--;
}
else{
if(ss[pos] == 1){
update(pos,n,1,-1);
}
else if(ss[pos] == -1){
update(pos,n,1,1);
}
ss[pos] = 0;
}
if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
ans.push_back(query_max(1,n,1));
}
else{
ans.push_back(-1);
}
}
for(int i = 0;i