题目:http://acm.hdu.edu.cn/showproblem.php?pid=4046

 

题意:给出一个字符串,统计这个字符串任意区间中“wbw”出现的次数。

规定两种操作,一是查询任意区间“wbw”出现次数;二是修改某一位置的字符。

 

分析:比较明显的线段树,单点更新,区间查询。

线段树记录的信息是区间中出现“wbw”字符的个数,线段树的叶子节点[i,i]记录字符串str中

str[i-2][i-1][i]是否是“wbw“。

对于字符的修改,这里就有要注意了。修改的位置pos, 可能对线段树中sum[pos-1]   sum[pos] 或sum[pos+1]

造成影响。这里要分情况。

 

代码

#include<cstdio>
#include<cstring>

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

using namespace std;

const int maxn=50010;
int n,m,sum[maxn<<2];
char str[maxn];
int num[maxn];

void pushup(int rt)
{
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void build(int l,int r,int rt)
{
	if(l==r)
	{
		sum[rt]=num[l];
		return;
	}
	int m=(l+r)>>1;
	build(lson);
	build(rson);
	pushup(rt);
}

int query(int L,int R,int l,int r,int rt)
{
	if(L<=l&&r<=R)
	{
		return sum[rt];
	}
	int m=(l+r)>>1;
	int ans=0;
	if(L<=m) ans+=query(L,R,lson);
	if(R>m)  ans+=query(L,R,rson);
	return ans;
}

void update(int p,int val,int l,int r,int rt)
{
	if(l==r)
	{
		sum[rt]=val;
		return;
	}
	int m=(l+r)>>1;
	if(p<=m) update(p,val,lson);
	else 	 update(p,val,rson);
	pushup(rt);
}

int main()
{
	int t,T;
	scanf("%d",&T);
	for(int t=1;t<=T;t++)
	{
		printf("Case %d:\n",t);
		scanf("%d%d%s",&n,&m,str+1);

		memset(num,0,sizeof(num));
		for(int i=3;i<=n;i++)
			if(str[i-2]=='w'&&str[i-1]=='b'&&str[i]=='w')  num[i]=1;
		build(1,n,1);

		int k,a,b;
		char ch[5];
		while (m--)
		{
			scanf("%d",&k);
			if(k==0)
			{
				scanf("%d%d",&a,&b);
				a++;b++;   //字符串从1开始,所以下标都加1
				if(b-a<2)  printf("0\n");
				else       printf("%d\n",query(a+2,b,1,n,1));

			}
			else
			{
				scanf("%d%s",&a,ch);
				a++;
				if(ch[0]==str[a]) continue;//修改的和以前一样,这不用任何操作
				if(a>=3)
				{
					if(str[a-2]=='w'&&str[a-1]=='b'&&str[a]=='w')
						update(a,0,1,n,1);
					if(str[a-2]=='w'&&str[a-1]=='b'&&str[a]=='b')
						update(a,1,1,n,1);
				}
				if(a>=2&&a+1<=n)
				{
					if(str[a-1]=='w'&&str[a]=='b'&&str[a+1]=='w')
						update(a+1,0,1,n,1);
					if(str[a-1]=='w'&&str[a]=='w'&&str[a+1]=='w')
						update(a+1,1,1,n,1);
				}
				if(a+2<=n)
				{
					if(str[a]=='w'&&str[a+1]=='b'&&str[a+2]=='w')
						update(a+2,0,1,n,1);
					if(str[a]=='b'&&str[a+1]=='b'&&str[a+2]=='w')
						update(a+2,1,1,n,1);
				}
				str[a]=ch[0];

			}

		}
	}
	return 0;
}

HDU—4046 Panda (线段树)的更多相关文章

  1. hdu 4046 Panda [线段树]

    Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  2. HdU 4046 Panda 段树

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4046 意甲冠军:到了bw组成的长度为n的字符串(n<=50000).有m次操作(m<=1000 ...

  3. HDU 4046 Panda(树状数组)

    Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  4. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  5. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  6. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  8. HDU 5877 dfs+ 线段树(或+树状树组)

    1.HDU 5877  Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...

  9. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

随机推荐

  1. 1251 client does not support

    1.mysql -uroot -p 123456        (用户root,密码123465) 2.use mysql: 3.ALTER USER 'root'@'localhost' IDENT ...

  2. JQuery中内容操作函数、validation表单校验

    JQuery:内容体拼接(可以直接拼接元素节点和内容节点) JQuery实现: 方案1:A.append(B); == B.appendTo(A);A的后面拼接B 方案2: A.prepend(B); ...

  3. 净心诀---python3生成器

    生成器的作用----减少程序运行的内存开销 生成器特点: 1.一个一个的取值,而不是一次性把所有数据创建出来,迭代器中的数据不取不创建2.只能按照顺序取,不能跳过也不能回头3.一个迭代器中的数据只能从 ...

  4. 多个串的最长公共子串 SPOJ - LCS2 后缀自动机

    题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长 ...

  5. GetModuleHandleW 分析

    首先查询MSDN,可以清楚地看到 位于kernel32 dll 里面. 有目标就好办,找到这个dll,然后,开工,进入IDA. 跳啊 就到下面那块了. 遗憾的是...显然不是这里阿,实际上下一块调用的 ...

  6. Linux程序设计学习笔记(独乐乐版)

    在Android的开发过程中经常会遇到Linux相关的问题,为了更彻底的了解Linux准备整点没用的,找到一本 <Linux程序设计>开始系统的学习. 期间记录下自认为重要的内容,本以为是 ...

  7. WSGI——python-Web框架基础

    1. 简介 WSGI ​ WSGI:web服务器网关接口,这是python中定义的一个网关协议,规定了Web Server如何跟应用程序交互.可以理解为一个web应用的容器,通过它可以启动应用,进而提 ...

  8. JUC 一 ReentrantLock 可重入锁

    java.util.concurrent.locks ReentrantLock即可重入锁,实现了Lock和Serializable接口 ReentrantLock和synchronized都是可重入 ...

  9. SQL Server 获取所有库名

    ----1. 获取所有的数据库名----- SELECT NAME FROM MASTER.DBO.SYSDATABASES ORDER BY NAME   -----2. 获取所有的表名------ ...

  10. 在线暴躁:<script />问题

    这个问题是今天发现的,以前都没注意到这个问题: <script src="./vue/vue.min.js" /> <script src="./vue ...