zoukankan      html  css  js  c++  java
  • csu 1809 Parenthesis(线段树)

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    char s[maxn];
    int  pre[maxn],Min[maxn<<2];
    int n,q,u,v;
    /*
    	给一个长度为n(<=1e5)的只有()的匹配字符串,q(<=1e5)次询问
    	每次询问在原串上交换两个字符,问交换之后是否还是合法子串
    	如果把(值为1,)值为-1,那么一个区间前缀和不存在<0,并且
    	最终的和为0,肯定就是一个匹配字符串
    	那么交换的两个字符是相同的,肯定是合法的
    	如果交换的是 )(,那么肯定也是合法的
    	如果交换的是(),那么就要考虑[l,r)之间在交换后是否会产生
    	负数,交换的结果是,[l,r)都会-2,那么求[l,r)之间的最小值
    	写个线段树就好了
    */
    
    void build(int rt,int l,int r){
    	if(l==r){
    		Min[rt]=pre[l];
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(rt<<1,l,mid);
    	build(rt<<1|1,mid+1,r);
    	Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
    }
    
    int query(int rt,int l,int r,int ql,int qr){
    	if(ql<=l&&qr>=r)return Min[rt];
    	
    	int mid=(l+r)>>1;
    	int res=INT_MAX;
    	if(ql<=mid)res=min(res,query(rt<<1,l,mid,ql,qr));
    	if(qr>mid)res=min(res,query(rt<<1|1,mid+1,r,ql,qr));
    	return res;
    }
    
    int main(){
    	int n,q,u,v;
    	while(~scanf("%d%d",&n,&q)){
    		getchar();gets(s);
    		for(int i=1;i<=n;i++){
    			if(s[i-1]=='(')pre[i]=1;
    			else pre[i]=-1;
    			pre[i]+=pre[i-1];
    		}
    		build(1,1,n);
    		
    		while(q--){
    			scanf("%d%d",&u,&v);
    			if(u>v)swap(u,v);
    			if(s[u-1]==s[v-1])puts("Yes");
    			else if(s[v-1]=='(')puts("Yes");
    			else{
    				int a=query(1,1,n,u,v-1);
    				if(a>1)puts("Yes");
    				else puts("No");
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Java架构师成长直通车百度云
    java架构师直通车百度云
    java架构师成长直通车
    初级Java程序员需要掌握哪些主流技术
    JAVA互联网架构师专题/分布式/高并发/微服务之咕泡学院学习笔记
    java架构师学习之路
    新手都能学懂的SpringBoot
    2020新版python最新就业班项目实战教程(完整)
    35个jQuery小技巧!
    web知识总结
  • 原文地址:https://www.cnblogs.com/jihe/p/6678156.html
Copyright © 2011-2022 走看看