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