您的位置:首页 > 其它

HDU 4046 - Panda (线段树 + 单点更新)

2014-11-02 12:49 351 查看


题意

给出一个字符串,有两种操作。一种是询问[l, r]里有几个wbw,还有是修改某个点的字符。


思路

可以用一个点表示这个点的前三个是不是组成wbw,是就1,不是0.这样就可以通过线段树来处理。

如果修改了一个点,就要修改另外被影响的两个点。


代码

#include <cstdio>

#include <stack>

#include <set>

#include <iostream>

#include <string>

#include <vector>

#include <queue>

#include <functional>

#include <cstring>

#include <algorithm>

#include <cctype>

#include <string>

#include <map>

#include <cmath>

#define LL long long

#define SZ(x) (int)x.size()

#define Lowbit(x) ((x) & (-x))

#define MP(a, b) make_pair(a, b)

#define MS(arr, num) memset(arr, num, sizeof(arr))

#define PB push_back

#define F first

#define S second

#define ROP freopen("input.txt", "r", stdin);

#define MID(a, b) (a + ((b - a) >> 1))

#define LC rt << 1, l, mid

#define RC rt << 1|1, mid + 1, r

#define LRT rt << 1

#define RRT rt << 1|1

#define BitCount(x) __builtin_popcount(x)

const double PI = acos(-1.0);

const int INF = 0x3f3f3f3f;

using namespace std;

const int MAXN = 5e4 + 10;

const int MOD = 100000007;


typedef pair<int, int> pii;

typedef vector<int>::iterator viti;

typedef vector<pii>::iterator vitii;


int vmax[MAXN << 2];


char str[MAXN];


void PushUp(int rt)

{

vmax[rt] = vmax[LRT] + vmax[RRT];

}


void Build(int rt, int l, int r)

{

if (l == r)

{

if (l >= 3)

if (str[l] == 'w' && str[l - 1] == 'b' && str[l - 2] == 'w') vmax[rt] = 1;

else vmax[rt] = 0;

else vmax[rt] = 0;

return;

}

int mid = MID(l, r);

Build(LC); Build(RC);

PushUp(rt);

}


void Update(int rt, int l, int r, int pos)

{

if (l == r)

{

if (str[l] == 'w' && str[l - 1] == 'b' && str[l - 2] == 'w') vmax[rt] = 1;

else vmax[rt] = 0;

return;

}

int mid = MID(l, r);

if (pos <= mid) Update(LC, pos);

else Update(RC, pos);

PushUp(rt);

}


int Query(int rt, int l, int r, int L, int R)

{

if (L <= l && r <= R) return vmax[rt];

int mid = MID(l, r), ans = 0;

if (L <= mid) ans += Query(LC, L, R);

if (R > mid) ans += Query(RC, L, R);

return ans;

}


int main()

{

//ROP;

int T, i, j, cases = 0;

scanf("%d", &T);

while (T--)

{

printf("Case %d:\n", ++cases);

int m, n;

scanf("%d%d", &m, &n);

scanf("%s", str + 1);

Build(1, 1, m);

while (n--)

{

int a, b;

scanf("%d%d%*c", &a, &b);

if (a == 0)

{

int c;

scanf("%d", &c);

if (c - b < 2)

    {

puts("0");

continue;

}

printf("%d\n", Query(1, 1, m, b + 3, c + 1));

}

else

{

b++;

char c;

scanf("%c", &c);

str[b] = c;

if (b >= 3) Update(1, 1, m, b);

if (b >= 2 && b + 1 <= m) Update(1, 1, m, b + 1);

if (b >= 1 && b + 2 <= m) Update(1, 1, m, b + 2);

}


}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM HDU