• 【SPOJ61】Brackets(线段树)


    题意:给出一个括号序列,要求维护两种操作:

    1.将第x位上的括号取反

    2.查询当前整个括号序列是否匹配

    n<=3e4

    思路:线段树维护区间内没有匹配的左右括号数量

    pushup时t[p].r=t[rs].r+t[ls].r-min(t[ls].l,t[rs].r)

    不知道这个式子怎么推出来的,但在四种情况下它都成立

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned int uint;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> PII;
     16 typedef vector<int> VI;
     17 #define fi first
     18 #define se second
     19 #define MP make_pair
     20 #define N   210000
     21 #define M   7010
     22 #define eps 1e-8
     23 #define pi  acos(-1)
     24 #define oo  1e9
     25 #define MOD 10007
     26 
     27 struct node
     28 {
     29     int l,r;
     30 }t[N];
     31 char a[N];
     32 int n;
     33 
     34 
     35 void pushup(int p)
     36 {
     37     int ls=p<<1; 
     38     int rs=ls+1;
     39     t[p].l=t[ls].l+t[rs].l-min(t[ls].l,t[rs].r);
     40     t[p].r=t[rs].r+t[ls].r-min(t[ls].l,t[rs].r);
     41 }
     42 
     43 void build(int l,int r,int p)
     44 {
     45     t[p].l=t[p].r=0;
     46     if(l==r)
     47     {
     48         if(a[l]=='(') t[p].l=1;
     49          else t[p].r=1;
     50         return;
     51     }
     52     int mid=(l+r)>>1;
     53     build(l,mid,p<<1);
     54     build(mid+1,r,p<<1|1);
     55     pushup(p);
     56 }
     57 
     58 void update(int l,int r,int x,int p)
     59 {
     60     if(l==r)
     61     {
     62         t[p].l=1-t[p].l;
     63         t[p].r=1-t[p].r;
     64         return;
     65     }
     66     int mid=(l+r)>>1;
     67     if(x<=mid) update(l,mid,x,p<<1);
     68      else update(mid+1,r,x,p<<1|1);
     69     pushup(p);
     70 }
     71 
     72 int main()
     73 {
     74     //freopen("spoj61.in","r",stdin);
     75     //freopen("spoj61.out","w",stdout); 
     76     int cas=0;
     77     while(scanf("%d",&n)!=EOF)
     78     {
     79         cas++;
     80         printf("Test %d:
    ",cas);
     81         scanf("%s",a+1);
     82         int m;
     83         scanf("%d",&m);
     84         build(1,n,1); 
     85         for(int i=1;i<=m;i++)
     86         {
     87             int x;
     88             scanf("%d",&x);
     89             if(x==0) 
     90             {
     91                 if(t[1].l==0&&t[1].r==0) printf("YES
    ");
     92                  else printf("NO
    ");
     93             }
     94              else update(1,n,x,1);
     95         }
     96     }
     97     return 0;
     98 }
     99     
    100     
  • 相关阅读:
    泛型的内部原理:类型擦除以及类型擦除带来的问题
    Redis的那些最常见面试问题
    线程池全面解析
    对线程调度中Thread.sleep(0)的深入理解
    集群环境下Redis分布式锁
    3.8
    3.7
    3.6任务
    3.5任务
    3.4
  • 原文地址:https://www.cnblogs.com/myx12345/p/9862069.html
Copyright © 2020-2023  润新知