hdu4046(线段树)

来源:互联网 发布:柴犬为什么会笑 知乎 编辑:程序博客网 时间:2024/06/05 15:15

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

Panda

Time Limit: 10000/4000 MS (Java/Others) Memory Limit: 32768/32768 K(Java/Others)
Total Submission(s): 1516 Accepted Submission(s):511


Problem Description
When I wrote down this letter, you may have been on theairplane to U.S.
We have known for 15 years, which has exceeded one-fifth of mywhole life. I still remember the first time we went to the movies,the first time we went for a walk together. I still remember thesmiling face you wore when you were dressing in front of themirror. I love your smile and your shining eyes. When you are withme, every second is wonderful.
The more expectation I had, the more disappointment I got. You saidyou would like to go to U.S.I know what you really meant. I respectyour decision. Gravitation is not responsible for people falling inlove. I will always be your best friend. I know the way isdifficult. Every minute thinking of giving up, thinking of thereason why you have held on for so long, just keep going on.Whenever you’re having a bad day, remember this: I LOVE YOU.
I will keep waiting, until you come back. Look into my eyes and youwill see what you mean to me.
There are two most fortunate stories in my life: one is finally thetime I love you exhausted. the other is that long time ago on aparticular day I met you.
Saerdna.

It comes back to several years ago. I still remember your immatureface.
The yellowed picture under the table might evoke the countlessmemory. The boy will keep the last appointment with the girl, missthe heavy rain in those years, miss the love in those years. Havingtried to conquer the world, only to find that in the end, you arethe world. I want to tell you I didn’t forget. Starry night, I willhold you tightly.

Saerdna loves Panda so much, and also you know that Panda has twocolors, black and white.
Saerdna wants to share his love with Panda, so he writes a loveletter by just black and white.
The love letter is too long and Panda has not that much time to seethe whole letter.
But it's easy to read the letter, because Saerdna hides his love inthe letter by using the three continuous key words that are white,black and white.
But Panda doesn't know how many Saerdna's love there are in theletter.
Can you help Panda?


 

Input
An integer T means the number of test casesT<=100
For each test case:
First line is two integers n, m
n means the length of the letter, m means the query of the Panda.n<=50000,m<=10000
The next line has n characters 'b' or 'w', 'b' means black, 'w'means white.
The next m lines
Each line has two type
Type 0: answer how many love between L and R.(0<=L<=R
Type 1: change the kth character toch(0<=k


 

Output
For each test case, output the case number first.
The answer of the question.


 

Sample Input
2 5 2 bwbwb0 0 4 0 1 3 5 5 wbwbw 0 0 4 0 0 2 0 2 4 1 2 b 0 0 4


 

Sample Output
Case 1: 1 1Case 2: 2 1 1 0


 

Source
The 36th ACM/ICPC Asia Regional Beijing Site —— OnlineContest


 

Recommend
lcy
果断参考大神的代码。。hdu4046(线段树)看了半天终于看懂了。
参考出处:http://hi.baidu.com/517145/item/f3d3c539f3d8409ef4e4ad0e
作者:未知。
题意:给你一个字符串,由'w' 和 'b' 组成,对该字符串有俩个操作,
当输入为0时,询问该区间[a,b] 内有多少个串 为 "wbw";
当输入为0时,将下标为k的字符改为输入的字符;
注意:这里的a,b,k表示的都是字符串的下标,也就是取值范围为[0,n-1];
分析:
对这种区间修改或询问的题目,首先想到的就是线段树或者树状数组了,不过还是线段树熟悉一点,
我用线段树做的 ,关键还是构造模型,区间内每一个点的值表示的是什么?
我是这样表示的,每一个点表示的是以该下标结束的长度为3的子串是否为"wbw",
若是,则等于1,否则等于0,保存在数组a[]中。
以,当进行区间询问时,对[a,b]的询问则应该改为对区间[a+2,b],当然这里对a+2,和b的大小还是要讨论的;
当进行点修改时,则可能要修改三个点,因为改动一个字符时,
会影响到三个长度为3的子串,所以有可能进行三次修改(之前在这里对条件的判断似乎不太严格,一直WA);
#include<stdio.h>
#include<iostream>
#include<memory.h>
#include<string.h>
using namespace
std;
#define MAX 50012
struct node
{

   int
l,r,c;
};

struct
node tree[MAX*4];
#define Mid(idx)(tree[idx].l+tree[idx].r)>>1
intnum[MAX*5];
void
buildTree(intidx,int l,intr)
{

   tree[idx].l=l;
   tree[idx].r=r;
   tree[idx].c=-1;
   if
(r==l)
   {

       tree[idx].c=num[l];
       return
;
   }

   int
mid=(l+r)>>1;
   buildTree(idx<<1,l,mid);
   buildTree(idx<<1|1,mid+1,r);
   tree[idx].c=tree[idx<<1].c+tree[idx<<1|1].c;
}

void
Insert(intidx,int i,intc)
{

   if
(tree[idx].l==i&&i==tree[idx].r)
   {

       tree[idx].c=c;
       return
;
   }

   int
mid=Mid(idx);
   if
(i>mid) Insert(idx<<1|1,i,c);//i>mid就可以了,我土血啊,
   else Insert(idx<<1,i,c);
   tree[idx].c=tree[idx<<1].c+tree[idx<<1|1].c;//计算区间和
}
int
querySum(intidx,int l,intr)
{

   if
(tree[idx].l==l&&tree[idx].r==r)
   {

       return
tree[idx].c;
   }

   int
mid=Mid(idx);
   if
(mid>=r)return querySum(idx<<1,l,r);
    elseif
(l>mid) returnquerySum(idx<<1|1,l,r);
   else

   {

       return
querySum(idx<<1,l,mid)+querySum(idx<<1|1,mid+1,r);
    }
}

int
main()
{

   int
T,n,m,i,type,l,r,indx,iCase=0;
   char
str[MAX*5],temp;
   scanf("%d",&T);
   while
(T--)
   {

       memset(num,0,sizeof(num));

       scanf("%d%d",&n,&m);
       scanf("%s",&str);
       num[1]=0;
       printf("Case %d:\n",++iCase);
       for
(i=2; i<n; i++)
       {

           if
(str[i-2]=='w'&&str[i-1]=='b'&&str[i]=='w')
               num[i]=1;
           else
 
               num[i]=0;
       }

       num[n]=0;
       buildTree(1,1,n);
       for
(i=0; i<m; i++)
       {

           scanf("%d",&type);
           if
(0==type)
           {

               scanf("%d%d",&l,&r);
               if
(l+2>r)//询问的区间长度<3直接输出0
               {
                   cout<<0<<endl;
                   continue
;
               }
//否则从l+2开始询问
               cout<<querySum(1,l+2,r)<<endl;
           }

           else

           {

               scanf("%d%c",&indx,&temp);
               if
(temp==str[indx])continue;//若要就该的字符跟原先相同,则不用修改了
               if(indx>=2&&str[indx-2]=='w'&&str[indx-1]=='b'&&str[indx]=='w')
               {

                   Insert(1,indx,0);
                   num[indx]=0;
               }

               if
(indx>=2&&str[indx-2]=='w'&&str[indx-1]=='b'&&temp=='w')
               {

                       Insert(1,indx,1);
                       num[indx]=1;
               }

               if
(indx>=1&&indx+1<n&&str[indx-1]=='w'&&str[indx]=='b'&&str[indx+1]=='w')
               {

                   Insert(1,indx+1,0);
                   num[indx+1]=0;
               }

               if
(indx>=1&&indx+1<n&&str[indx-1]=='w'&&temp=='b'&&str[indx+1]=='w')
               {

                       Insert(1,indx+1,1);
                       num[indx+1]=1;
               }

               if
(indx>=0&&indx+2<n&&str[indx]=='w'&&str[indx+1]=='b'&&str[indx+2]=='w')
               {

                   Insert(1,indx+2,0);
                   num[indx+2]=0;
               }

               if
(indx>=0&&indx+2<n&&temp=='w'&&str[indx+1]=='b'&&str[indx+2]=='w')
               {

                       Insert(1,indx+2,1);
                       num[indx+2]=1;
               }

               str[indx]=temp;
           }
       }
   }

   return
0;
}