zoukankan      html  css  js  c++  java
  • UESTC 1546 Bracket Sequence (线段树+求和性质)

    题意:给定你长度为n的括号序列,动态对区间去反,赋值(括号),询问是否匹配,

    解题思路:这个题利用到了线段数求和的性质,对‘(’赋值为1,对 ‘)’括号赋值为-1,就转化为前缀和必须大于等于0且区间和等于0,根据这个判断即可。

    解题代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #define maxn 100005
      5 char str[maxn];
      6 struct node{
      7     int l, r, m ;
      8     int sum , c , f; 
      9 }tree[maxn*4];
     10 int L(int c){
     11     return c*2;
     12 }
     13 int R(int c){
     14     return c*2+1;
     15 }
     16 void fxor(int c){
     17     if(tree[c].c != 0 ){
     18         tree[c].c  =  -tree[c].c;
     19         tree[c].sum = tree[c].c*(tree[c].r - tree[c].l + 1);
     20     }
     21     else {        
     22         tree[c].f ^= 1;
     23     }
     24 
     25 }
     26 void Pushup(int c){
     27     tree[c].sum = tree[L(c)].sum + tree[R(c)].sum;
     28     if(tree[L(c)].c == tree[R(c)].c && tree[L(c)].c != 0)
     29         tree[c].c = tree[L(c)].c;
     30     else tree[c].c = 0;
     31 }
     32 void Pushdown(int c){
     33     if(tree[c].c != 0 ){
     34         tree[L(c)].c = tree[R(c)].c = tree[c].c;
     35         tree[L(c)].sum = tree[c].c *(tree[L(c)].r - tree[L(c)].l +1);
     36         tree[R(c)].sum = tree[c].c *(tree[R(c)].r - tree[R(c)].l +1);
     37         tree[R(c)].f = tree[L(c)].f  = 0 ;
     38     }
     39     if(tree[c].f){
     40         fxor(L(c));
     41         fxor(R(c));
     42         tree[c].f = 0 ;
     43     }
     44 }
     45 void build(int c, int p , int v)
     46 {
     47     tree[c].l = p ; 
     48     tree[c].r = v ;
     49     tree[c].m = (p+v)/2;
     50     tree[c].sum = 0 ; 
     51     tree[c].c = 0;
     52     tree[c].f = 0 ;
     53     if(p == v ){
     54         if(str[p] == '('){
     55             tree[c].c = 1; 
     56             tree[c].sum = 1; 
     57         }
     58         else {
     59             tree[c].c = -1;
     60             tree[c].sum = -1;
     61         }
     62         return ;
     63     }
     64     build(L(c),p,tree[c].m);
     65     build(R(c),tree[c].m+1,v);
     66     Pushup(c);
     67 }
     68 void update(int c , int p , int  v, int value){
     69     if(p <= tree[c].l  && v >= tree[c].r) {
     70         tree[c].c = value;
     71         tree[c].f = 0 ;
     72         tree[c].sum  = tree[c].c * (tree[c].r - tree[c].l +1);
     73         return ;
     74     }
     75     Pushdown(c);
     76     if(v <= tree[c].m ) update(L(c),p,v,value);
     77     else if(p > tree[c].m) update(R(c),p,v,value);
     78     else {
     79         update(L(c),p,tree[c].m,value);
     80         update(R(c),tree[c].m+1,v,value);
     81     }
     82     Pushup(c);
     83 }
     84 void fan(int c, int p , int v){
     85     if(p <= tree[c].l && v >= tree[c].r)  {
     86         fxor(c);
     87         return ;
     88     }
     89     Pushdown(c);
     90     if(v <= tree[c].m ) fan(L(c),p,v);
     91     else if(p > tree[c].m) fan(R(c),p,v);
     92     else {
     93         fan(L(c),p,tree[c].m);
     94         fan(R(c),tree[c].m+1,v);
     95     }
     96     Pushup(c);
     97 
     98 }
     99 int tsum =0 ;
    100 int ok = 1;
    101 
    102 void getsum(int c, int p, int v ){
    103     if(ok == 0 )
    104         return;
    105     if(p <= tree[c].l && v >= tree[c].r){
    106         if(tree[c].c != 0){
    107             tsum += tree[c].sum ;
    108             if(tsum < 0 )
    109                 ok = 0 ;
    110             return; 
    111         }else {
    112             Pushdown(c);
    113             getsum(L(c),p,tree[c].m);
    114             getsum(R(c),tree[c].m+1,v);
    115             return;
    116         }
    117     }
    118     Pushdown(c);
    119     if(v <= tree[c].m) getsum(L(c),p,v);
    120     else if(p > tree[c].m) getsum(R(c),p,v);
    121     else {
    122         getsum(L(c),p,tree[c].m);
    123         getsum(R(c),tree[c].m+1,v);
    124     }
    125 }
    126 int main()
    127 {
    128     int t; 
    129     //       freopen("/home/plac/problem/input.txt","r",stdin);
    130     scanf("%d",&t);
    131     //  freopen("/home/plac/problem/output.txt","w",stdout);
    132     for(int CASE = 1; CASE <= t; CASE ++){
    133         int n ;
    134         scanf("%d",&n);
    135         scanf("%s",str);
    136         build(1,0,n-1);
    137         int q; 
    138         scanf("%d",&q);
    139         printf("Case %d:
    ",CASE);
    140         while(q--)
    141         {
    142             int a, b ;
    143             char t1[10],t2[2];
    144             scanf("%s %d %d",t1,&a,&b);
    145             if(t1[0] == 'r'){
    146                 fan(1,a,b);
    147             }else if(t1[0] == 'q'){
    148                 tsum = 0 ; 
    149                 ok  = 1;
    150                 getsum(1,a,b);
    151                 if(ok == 1 && tsum == 0 && (b-a+1)%2 == 0)
    152                     printf("YES
    ");
    153                 else 
    154                     printf("NO
    ");
    155 
    156             }else{
    157                 scanf("%s",t2);
    158                 if(t2[0] == '(')
    159                     update(1,a,b,1);
    160                 else 
    161                     update(1,a,b,-1);
    162             }
    163 
    164         }
    165         printf("
    ");
    166     }
    167     return 0 ; 
    168 }
    View Code

     PS。这题卡常数。需要优化,我在getsum里面优化了一下就过了

    if(k == 0 )
       return;
    没有梦想,何谈远方
  • 相关阅读:
    51.try块和catch块中return语句的执行
    17. 处理日期
    16.查找特定字符出现的次数
    15.字符串长度
    14.字符串拆分
    13.字符串比较
    12.幸运抽奖
    11.使用枚举
    10.获取系统时间
    MSSQL 判断临时表是否存在
  • 原文地址:https://www.cnblogs.com/zyue/p/3266290.html
Copyright © 2011-2022 走看看