CSU1809 Parenthesis(贪心+线段树)
来源:互联网 发布:ubuntu pycharm pyqt5 编辑:程序博客网 时间:2024/05/06 11:10
观察发现几个规律:
1)交换相同的括号Yes
2)不符合1)的情况下,交换第一个位置或最后一个位置No
3)保证l<r,如果s[l] == ')', Yes
4)如果 s[l] == '(',交换之后l位置会至少出现2个连续的')',那么就要求l位置之前至少要有2个'(',同样,r位置也会出现两个'(',要求r位置之后至少要有两个')'。
发现第4点之后用2个树状数组或者线段树应该就能做出来,但是代码应该会很乱……还要考虑一些特殊情况。更好的办法是维护一个“前缀和”数组。遇到'(' +1,')' -1;,查询的时候如果[l,r-1]之间有sum[i]<2则No,说明前面抵消之后不足两个’(‘补充。如果在[l,r-1]之间都满足,由于之前就是平衡的,在r之后也必定满足。
【代码】
/* ***********************************************Author :angon************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <stack>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)#define lld %I64d#define REP(i,k,n) for(int i=k;i<n;i++)#define REPP(i,k,n) for(int i=k;i<=n;i++)#define scan(d) scanf("%d",&d)#define scanl(d) scanf("%I64d",&d)#define scann(n,m) scanf("%d%d",&n,&m)#define scannl(n,m) scanf("%I64d%I64d",&n,&m)#define mst(a,k) memset(a,k,sizeof(a))#define LL long long#define N 1005#define mod 1000000007inline int read(){int s=0;char ch=getchar();for(; ch<'0'||ch>'9'; ch=getchar());for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0';return s;}char s[100005];int sum[100005];struct node{ int l,r,val;}seg[100005*4];void build(int i,int l,int r){ seg[i].l=l; seg[i].r=r; if(l==r) { seg[i].val = sum[l]; return ; } int mid = (l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); seg[i].val = min(seg[i<<1].val,seg[i<<1|1].val);}int query(int i,int l,int r){ if(l<=seg[i].l && r>=seg[i].r) { return seg[i].val; } int ret = 1e9; int mid = (seg[i].l+seg[i].r)>>1; if(mid>=l) ret = min(ret,query(i<<1,l,r)); if(mid<r) ret = min(ret,query(i<<1|1,l,r)); return ret;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,q; while(~scann(n,q)) { scanf("%s",s+1); mst(sum,0); REPP(i,1,n) if(s[i]=='(') sum[i] = sum[i-1] + 1; else sum[i] = sum[i-1] - 1; build(1,1,n); while(q--) { int l,r; scann(l,r); if(l>r) swap(l,r); if(s[l] == s[r] || s[l]==')') puts("Yes"); else if(l==1 || r==n) puts("No"); else { int ret = query(1,l,r-1); if(ret<2) puts("No"); else puts("Yes"); } } } return 0;}/*8 5(((())))1 52 63 47 84 612 8((((()()))))1 52 63 47 84 61 92 114 128 2()()()()1 52 816 6(((()))()())()()1 23 144 54 98 1111 12NoYesYesYesYesYesYesYesYesYesNoYesNoYesYesYesNoYesNoNoYes*/
0 0
- CSU1809 Parenthesis(贪心+线段树)
- 【CSU1809】Parenthesis(线段树 + 贪心 + 前缀和)
- CSU1809 Parenthesis(前缀和+括号匹配)
- 2016湖南省省赛G-Parenthesis(CSU1809)
- CSU 1809 Parenthesis(RMQ||线段树)
- CSU 1809 Parenthesis (线段树)
- CSU 1809 Parenthesis(线段树前缀和)
- HHUOJ 1023 Mouse and Parenthesis(线段树)
- CSU 1809 Parenthesis (线段树)【2016年湖南省第十二届大学生计算机程序设计竞赛 - G】
- Contest1002 - HHU ACM 综合训练1 E题 Mouse and Parenthesis(线段树+括号匹配)
- CSU-1809:Parenthesis 括号匹配问题(线段树维护最小值)
- 贪心,括号序列(Rikka with Parenthesis II,HDU 5831)
- [CSU 1809: Parenthesis] 线段树/RMQ处理括号序列
- HHU Mouse and Parenthesis (线段树+括号匹配)
- CSU 1809 Parenthesis【思维+线段树】好题~
- V-Parenthesis 前缀+ZKW线段树或RMQ
- 线段树+贪心+UVALive5881
- HDU 5831 Rikka with Parenthesis II 【贪心】
- falshbuilder 永久破解方法
- 匿名函数
- 学习之gulp入门
- java 自己实现项目一键全转码 解决文件乱码问题
- NSURLSessionDataTask
- CSU1809 Parenthesis(贪心+线段树)
- Matlab GUI 界面设计基础(1)
- 嵌入式系统的组成
- 央行数字货币研究报告:法定数字币势在必行,或先应用于票据领
- [LeetCode] 132. Palindrome Partitioning II
- Codeforces Round #369 (Div. 2)B. Chris and Magic Square
- web前端学习之二 认识网页
- java 输入流和输出流
- 关于如何限定UITextField只能输入一个小数点的代码