分题每次我看的都是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;
}