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;
    没有梦想,何谈远方
  • 相关阅读:
    有点忙啊
    什么是协程
    HDU 1110 Equipment Box (判断一个大矩形里面能不能放小矩形)
    HDU 1155 Bungee Jumping(物理题,动能公式,弹性势能公式,重力势能公式)
    HDU 1210 Eddy's 洗牌问题(找规律,数学)
    HDU1214 圆桌会议(找规律,数学)
    HDU1215 七夕节(模拟 数学)
    HDU 1216 Assistance Required(暴力打表)
    HDU 1220 Cube(数学,找规律)
    HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)
  • 原文地址:https://www.cnblogs.com/zyue/p/3266290.html
Copyright © 2011-2022 走看看