题意:
两个操作,改变区间某个位置的值,询问区间好友wbw串的个数。
题解:
将线段树的每个点的值设为以这个点为结尾的串是否是wbw。接下来就是裸的线段树。注意一个位置改变会影响三个位置,所以要更新三个位置的点。区间更新是要这样做query(a+2,b,1)因为如果不这样会重复计算。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<vector> #include<queue> #include<map> #include<set> #include<stack> #define B(x) (1<<(x)) using namespace std; typedef long long ll; typedef unsigned long long ull; const int oo = 0x3f3f3f3f; const ll OO = 0x3f3f3f3f3f3f3f3f; const double eps = 1e-9; #define lson rt<<1 #define rson rt<<1|1 void cmax(int& a, int b){ if (b>a)a = b; } void cmin(int& a, int b){ if (b<a)a = b; } void cmax(ll& a, ll b){ if (b>a)a = b; } void cmin(ll& a, ll b){ if (b<a)a = b; } void cmax(double& a, double b){ if (a - b < eps) a = b; } void cmin(double& a, double b){ if (b - a < eps) a = b; } void add(int& a, int b, int mod){ a = (a + b) % mod; } void add(ll& a, ll b, ll mod){ a = (a + b) % mod; } const int MOD = 1000000007; const int maxn = 51000; char str[maxn]; struct SegTree{ int l, r, sum; int mid(){ return (l + r) >> 1; } }tree[maxn << 2]; void push_up(int rt){ tree[rt].sum = tree[lson].sum + tree[rson].sum; } bool ok(int pos){ if (pos - 2 >= 1 && str[pos - 2] == 'w'&&str[pos - 1] == 'b'&&str[pos] == 'w') return true; return false; } void build(int l, int r, int rt){ tree[rt].l = l; tree[rt].r = r; tree[rt].sum = 0; if (l == r){ tree[rt].sum = ok(r) ? 1 : 0; return; } int mid = (l + r) >> 1; build(l, mid, lson); build(mid + 1, r, rson); push_up(rt); } void update(int pos, int rt){ if (tree[rt].l == tree[rt].r && tree[rt].r == pos){ tree[rt].sum = ok(pos) ? 1 : 0; return; } int mid = tree[rt].mid(); if (pos <= mid) update(pos, lson); else if (pos >= mid + 1) update(pos, rson); push_up(rt); } int query(int l, int r, int rt){ if (l <= tree[rt].l && tree[rt].r <= r){ return tree[rt].sum; } int res = 0; int mid = tree[rt].mid(); if (l <= mid) res += query(l, r, lson); if (mid + 1 <= r) res += query(l, r, rson); return res; } int main(){ //freopen("E:\\read.txt", "r", stdin); int n, m, T, cas = 1; int op, a, b; char c; scanf("%d", &T); while (T--){ scanf("%d %d", &n, &m); scanf("%s", str + 1); build(1, n, 1); printf("Case %d:\n", cas++); while (m--){ scanf("%d", &op); if (op == 0){ scanf("%d %d", &a, &b); a++; b++; if (a + 2 <= b) printf("%d\n", query(a + 2, b, 1)); else printf("0\n"); } else{ scanf("%d %c", &a, &c); a++; if (str[a] != c){ str[a] = c; update(a, 1); if (a + 1 <= n) update(a + 1, 1); if (a + 2 <= n) update(a + 2, 1); } } } } return 0; }