您的位置:首页 > 其它

hdu 4046 Panda

2012-09-21 12:34 441 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4046

  简单线段树【单点修改,查询区间】,合并两个目标区间,查找区间中目标子串的个数,子串可以有重叠的部分!

AC代码:

View Code

#include <cstring>
#include <cstdio>
#include <cassert>
#include <algorithm>

using namespace std;

const int maxn = 50001;
int cnt[maxn << 2];

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

char str[maxn];

void up(int rt, int l, int m, int r) {
cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1];
if (m - l) {
if (str[m - 1] == 'w' && str[m] == 'b' && str[m + 1] == 'w') {
cnt[rt]++;
}
if (r - m > 1) {
if (str[m] == 'w' && str[m + 1] == 'b' && str[m + 2] == 'w') {
cnt[rt]++;
}
}
}
}

void build(int l, int r, int rt) {
if (l == r) {
cnt[rt] = 0;

return ;
}
int m = (l + r) >> 1;

build(lson);
build(rson);
up(rt, l, m, r);
}

void update(int pos, char ch, int l, int r, int rt) {
if (l == r) {
str[pos] = ch;

return ;
}
int m = (l + r) >> 1;

if (pos <= m) update(pos, ch, lson);
else update(pos, ch, rson);
up(rt, l, m, r);
}

struct Answer {
int l;
int r;
int cnt;
};

Answer query(int L, int R, int l, int r, int rt) {
Answer ret;

if (L <= l && r <= R) {
ret.l = l;
ret.r = r;
ret.cnt = cnt[rt];

return ret;
}
int m = (l + r) >> 1;

if (L <= m) {
ret = query(L, R, lson);
if (m < R) {
Answer tmp = query(L, R, rson);
ret.cnt += tmp.cnt;

int t = ret.r;

if (ret.r - ret.l) {

if (str[t - 1] == 'w' && str[t] == 'b' && str[t + 1] == 'w') {
ret.cnt++;
}
if (tmp.r - tmp.l) {
if (str[t] == 'w' && str[t + 1] == 'b' && str[t + 2] == 'w') {
ret.cnt++;
}
}
} else {
if (tmp.r - tmp.l) {
if (str[t] == 'w' && str[t + 1] == 'b' && str[t + 2] == 'w') {
ret.cnt++;
}
}
}
ret.r = tmp.r;
}
} else if (m < R) {
ret = query(L, R, rson);
}

return ret;
}

void deal() {
int n,m;

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

build(0, n - 1, 1);
while (m--) {
int op, l, r;
char ch[3];

scanf("%d", &op);
if (op) {
scanf("%d %s", &l, ch);
update(l, ch[0], 0, n - 1, 1);
} else {
scanf("%d%d", &l, &r);
printf("%d\n", query(l, r, 0, n - 1, 1).cnt);
}
}
}

int main() {
int T;

scanf("%d", &T);
for (int i = 1; i <= T; i++) {
printf("Case %d:\n", i);
deal();
}

return 0;
}


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