hdu 4046 Panda
http://acm.hdu.edu.cn/showproblem.php?pid=4046
简单线段树【单点修改,查询区间】,合并两个目标区间,查找区间中目标子串的个数,子串可以有重叠的部分!
AC代码:
View Code
1 #include <cstring> 2 #include <cstdio> 3 #include <cassert> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int maxn = 50001; 9 int cnt[maxn << 2]; 10 11 #define lson l, m, rt << 1 12 #define rson m + 1, r, rt << 1 | 1 13 14 char str[maxn]; 15 16 void up(int rt, int l, int m, int r) { 17 cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1]; 18 if (m - l) { 19 if (str[m - 1] == 'w' && str[m] == 'b' && str[m + 1] == 'w') { 20 cnt[rt]++; 21 } 22 if (r - m > 1) { 23 if (str[m] == 'w' && str[m + 1] == 'b' && str[m + 2] == 'w') { 24 cnt[rt]++; 25 } 26 } 27 } 28 } 29 30 void build(int l, int r, int rt) { 31 if (l == r) { 32 cnt[rt] = 0; 33 34 return ; 35 } 36 int m = (l + r) >> 1; 37 38 build(lson); 39 build(rson); 40 up(rt, l, m, r); 41 } 42 43 void update(int pos, char ch, int l, int r, int rt) { 44 if (l == r) { 45 str[pos] = ch; 46 47 return ; 48 } 49 int m = (l + r) >> 1; 50 51 if (pos <= m) update(pos, ch, lson); 52 else update(pos, ch, rson); 53 up(rt, l, m, r); 54 } 55 56 struct Answer { 57 int l; 58 int r; 59 int cnt; 60 }; 61 62 Answer query(int L, int R, int l, int r, int rt) { 63 Answer ret; 64 65 if (L <= l && r <= R) { 66 ret.l = l; 67 ret.r = r; 68 ret.cnt = cnt[rt]; 69 70 return ret; 71 } 72 int m = (l + r) >> 1; 73 74 if (L <= m) { 75 ret = query(L, R, lson); 76 if (m < R) { 77 Answer tmp = query(L, R, rson); 78 ret.cnt += tmp.cnt; 79 80 int t = ret.r; 81 82 if (ret.r - ret.l) { 83 84 if (str[t - 1] == 'w' && str[t] == 'b' && str[t + 1] == 'w') { 85 ret.cnt++; 86 } 87 if (tmp.r - tmp.l) { 88 if (str[t] == 'w' && str[t + 1] == 'b' && str[t + 2] == 'w') { 89 ret.cnt++; 90 } 91 } 92 } else { 93 if (tmp.r - tmp.l) { 94 if (str[t] == 'w' && str[t + 1] == 'b' && str[t + 2] == 'w') { 95 ret.cnt++; 96 } 97 } 98 } 99 ret.r = tmp.r; 100 } 101 } else if (m < R) { 102 ret = query(L, R, rson); 103 } 104 105 return ret; 106 } 107 108 void deal() { 109 int n,m; 110 111 scanf("%d%d", &n, &m); 112 scanf("%s", str); 113 114 build(0, n - 1, 1); 115 while (m--) { 116 int op, l, r; 117 char ch[3]; 118 119 scanf("%d", &op); 120 if (op) { 121 scanf("%d %s", &l, ch); 122 update(l, ch[0], 0, n - 1, 1); 123 } else { 124 scanf("%d%d", &l, &r); 125 printf("%d\n", query(l, r, 0, n - 1, 1).cnt); 126 } 127 } 128 } 129 130 int main() { 131 int T; 132 133 scanf("%d", &T); 134 for (int i = 1; i <= T; i++) { 135 printf("Case %d:\n", i); 136 deal(); 137 } 138 139 return 0; 140 }
——written by Lyon