分题每次我看的都是1 2 3.。。。今天第一题真是吓着我了。。囧。。
这题是LG看的,说是线段树,我当时觉得应该不是最简单的题,就去看其他题,后来CG说了,这题很简单,他把他思路跟我说了。
以三个字符代表一个点,插入线段树,更新的话,更新三个点,
比如 123456,这些,如果更新3,那么需要更新123,234,345这三个点。
这样的话,也就是更新到底,看是不是wbw,如果是的话,就标记为1,区间求和即可。
后来我们小盆友YY也过了。。。2秒+。我的线段树400+ms。。
#include <set> #include <map> #include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <string> #include <algorithm> #define MID(x,y) ( ( x + y ) >> 1 ) #define L(x) ( x << 1 ) #define R(x) ( x << 1 | 1 ) #define FOR(i,s,t) for(int i=(s); i<(t); i++) #define BUG puts("here!!!") #define STOP system("pause") #define file_r(x) freopen(x, "r", stdin) #define file_w(x) freopen(x, "w", stdout) using namespace std; const int MAX = 50010; char str[MAX]; struct Tnode{ // 一维线段树 int l,r; char val[5]; int sum; int len() { return r - l;} int mid() { return MID(l,r);} bool in(int ll,int rr) { return l >= ll && r <= rr; } void lr(int ll,int rr){ l = ll; r = rr;} }; Tnode node[MAX<<2]; void Updata_sum(int t) { node[t].sum = node[L(t)].sum + node[R(t)].sum; } void Build(int t,int l,int r) { node[t].lr(l,r); if( node[t].len() == 1 ) { node[t].sum = 0; node[t].val[0] = str[l]; node[t].val[1] = str[l+1]; node[t].val[2] = str[l+2]; if( str[l] == 'w' && str[l+1] == 'b' && str[l+2] == 'w' ) node[t].sum++; return ; } int mid = MID(l,r); Build(L(t),l,mid); Build(R(t),mid,r); Updata_sum(t); } void Updata(int t,int l,int r,char c,int k) { if( node[t].in(l,r) ) { node[t].val[k] = c; if( str[l] == 'w' && str[l+1] == 'b' && str[l+2] == 'w' ) node[t].sum = 1; else node[t].sum = 0; return ; } if( node[t].len() == 1 ) return ; int mid = node[t].mid(); if( l < mid ) Updata(L(t),l,r,c,k); if( r > mid ) Updata(R(t),l,r,c,k); Updata_sum(t); } int Query(int t,int l,int r) { if( node[t].in(l,r) ) return node[t].sum; if( node[t].len() == 1 ) return 0; int mid = node[t].mid(); int ans = 0; if( l < mid ) ans += Query(L(t),l,r); if( r > mid ) ans += Query(R(t),l,r); return ans; } int main() { int ncases, n, m, cmd, x, y, ind = 1; char s[10]; scanf("%d", &ncases); while( ncases-- ) { scanf("%d%d%s", &n, &m, str); Build(1, 0, n); printf("Case %d:\n", ind++); while( m-- ) { scanf("%d", &cmd); if( cmd == 0 ) { scanf("%d%d", &x, &y); if( y - x < 2 ) { printf("0\n"); continue; } int ans = Query(1, x, y-1); printf("%d\n", ans); } else { scanf("%d%s", &x, &s); if( str[x] == s[0] ) continue; str[x] = s[0]; if( x < n-2 ) // 更新第一个点 Updata(1, x, x+1, s[0], 0); if( x >= 2 ) //更新最后一个点 Updata(1, x-2, x-1, s[0], 2); if( x < n-1 && x > 0 ) Updata(1, x-1, x, s[0], 1); } } } return 0; }