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;
没有梦想,何谈远方
原文地址:https://www.cnblogs.com/zyue/p/3266290.html