首页 > 代码库 > csu 1809 Parenthesis(线段树)
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;}
csu 1809 Parenthesis(线段树)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。