hdu 4046 Panda (线段树 单点更新 区间查询)

来源:互联网 发布:电视直播软件live 编辑:程序博客网 时间:2024/04/24 11:16

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

题意:

给出你一个由w和b组成的字符串,再给出两种操作
1.问给定区间a~b上的wbw这样的串有多少个
2.将k位置的字符换成一个给出的字符

思路:

很典型的线段树区间查找,单点更新。
线段树维护的是在其区间内wbw这样节点的个数。在更新的时候判断一下左右儿子的连接处是否可以连成wbw就可以了。(此处要判越界等等一系列的细节很容易出错)。


code:

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>#define INF 1<<30using namespace std;const int maxn=60500;int dd[maxn],nn;char midcc[maxn];struct line{    int l,r,cc;} pp[4*maxn+1];void build(int k,int l,int r){    pp[k].l=l;    pp[k].r=r;    pp[k].cc=0;    if(l==r) return ;    build(2*k+1,l,(l+r)/2);    build(2*k+2,(l+r)/2+1,r);}void init(int n_){    nn=1;    while(nn<n_) nn*=2;    build(0,0,nn-1);}void update(int k){    k+=nn-1;    while(k>0){        k=(k-1)/2;        pp[k].cc=pp[2*k+1].cc+pp[2*k+2].cc;        if((pp[k].r-pp[k].l+1)<=2) continue;        int mid=pp[2*k+1].r;        if(dd[mid]==0&&dd[mid+1]==1&&dd[mid+2]==0) pp[k].cc++;        else if(dd[mid-1]==0&&dd[mid]==1&&dd[mid+1]==0) pp[k].cc++;    }}int query(int a,int b,int k){    if(pp[k].r<a||pp[k].l>b) return 0;    if(a<=pp[k].l&&pp[k].r<=b) return pp[k].cc;    else{        int vv=query(a,b,2*k+1)+query(a,b,2*k+2);        if((pp[k].r-pp[k].l+1)<=2||b<=pp[2*k+1].r||a>=pp[2*k+2].l) return vv;        int mid=pp[2*k+1].r;        if((mid+2)<=b&&dd[mid]==0&&dd[mid+1]==1&&dd[mid+2]==0) vv++;        else if((mid-1)>=a&&dd[mid-1]==0&&dd[mid]==1&&dd[mid+1]==0) vv++;        return vv;    }}int main(){    int T,n,m,kind,l,r;    char tt[5];    scanf("%d",&T);    for(int kk=1;kk<=T;kk++){        memset(dd,-1,sizeof(dd));        scanf("%d%d",&n,&m);        scanf("%s",midcc);        for(int i=0;i<n;i++){            if(midcc[i]=='b') dd[i]=1;            else dd[i]=0;        }        init(n);        for(int i=0;i<n;i++) update(i);        printf("Case %d:\n",kk);        while(m--){            scanf("%d",&kind);            if(!kind){                scanf("%d%d",&l,&r);                printf("%d\n",query(l,r,0));            }            else{                scanf("%d %1s",&l,tt);                if(tt[0]=='b') dd[l]=1;                else           dd[l]=0;                update(l);            }        }    }    return 0;}


0 0