• Codeforces 1263E Editor(前缀和数组基于线段树的RMQ)


    思路:

    1.在文本中,我们让(值为1)值为-1,其它值为0,将该文本看成一个int数组,我们就可以得到这个数组的前缀和数组;
    2.这个前缀和数组的最大值就是最多嵌套的层数;而最小值如果小于0则说明在从最左侧往右的某一段文本中,有)的数量多于(的情况,这是非法的;
    3.同时我们在执行指令的过程中,用一个变量ans来记录第一条里面提到的int数组的总和(其实就是前缀和数组的最后一个有效值),如果ans0则说明左右括号数相等了;
    4.既然查询数组最大/最小值,那就是典型的RMQ问题了,用线段树来做即可;因为涉及到区间修改问题,那引入lazy-tag标记就ok了~;
    4.最后如果前缀和数组最小值大于等于0ans==0,说明左右括号数相等且没有非法格式,输出我们的嵌套层数即可,否则就输出-1

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    inline void out(int x){if(x<0) {putchar('-'); x*=-1;}if(x>9) out(x/10); putchar(x%10+'0');}
    const int MAX_N=1e6+5;
    int tree[2][MAX_N<<2],tag[MAX_N<<2];  //tree[0]存最大值,tree[1]存最小值 
    #define rp(i) for(int i=0;i<2;i++)
    void push_down(int rt){
    	if(tag[rt]){
    		tag[rt<<1]+=tag[rt]; tag[rt<<1|1]+=tag[rt];
    		rp(i) tree[i][rt<<1]+=tag[rt],tree[i][rt<<1|1]+=tag[rt];
    		tag[rt]=0;
    	}
    }
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    void update(int a,int b,int c,int l,int r,int rt){
    	if(a<=l&&b>=r){
    		rp(i) tree[i][rt]+=c;
    		tag[rt]+=c;
    		return;
    	}
    	push_down(rt);
    	int mid=(l+r)>>1;
    	if(a<=mid) update(a,b,c,lson);
    	if(b>mid) update(a,b,c,rson);
    	tree[0][rt]=max(tree[0][rt<<1],tree[0][rt<<1|1]);   //往上更新 
    	tree[1][rt]=min(tree[1][rt<<1],tree[1][rt<<1|1]); 
    }
    char c[MAX_N];
    int main(){
    	int n; string s; int pos=1; int ans=0;
    	cin>>n>>s;
    	for(int i=0;i<=n;i++) c[i]='a';
    	for(int i=0;i<n;i++){
    		if(s[i]=='L') {if(pos>1) pos--;}
    		else if(s[i]=='R') pos++;
    		else if(s[i]=='('){
    			if(c[pos]!='('&&c[pos]!=')') update(pos,n,1,1,n,1),ans++;
    			else if(c[pos]==')') update(pos,n,2,1,n,1),ans+=2;
    			c[pos]='(';
    		}else if(s[i]==')'){
    			if(c[pos]!='('&&c[pos]!=')') update(pos,n,-1,1,n,1),ans--;
    			else if(c[pos]=='(') update(pos,n,-2,1,n,1),ans-=2;
    			c[pos]=')';
    		}else{
    			if(c[pos]=='(') update(pos,n,-1,1,n,1),ans--;
    			else if(c[pos]==')') update(pos,n,1,1,n,1),ans++;
    			c[pos]='a';
    		}
    		if(i) putchar(' ');
    		if(tree[1][1]<0||ans) out(-1);
    		else out(tree[0][1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    基于xmpp openfire smack开发之Android客户端开发[3]
    简单工厂,抽象工厂,工厂模式三者的对照
    【独具慧眼 推荐有礼】找出您心中的技术大牛 活动開始啦!
    ZOJ 3201
    具体解释站点沙盒期的原因表现与解决的方法
    工作,究竟意味着什么
    MVC之查询demo
    学习开淘宝网店
    快排的两种写法
    QTableWidget具体解释(样式、右键菜单、表头塌陷、多选等) (非代理)
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308776.html
Copyright © 2020-2023  润新知