码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4046 Panda(线段树)

时间:2015-03-10 10:24:52      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:在一串字符串中某个区间查询wbw的数目,更新某个位置的字符

思路:线段树,每个枝结点记录以这个点为中心的字符是不是wbw,所以每次某个位置更新的时候,左右两个位置均要更新

而且查询的时候某个区间的wbw的个数,位于边界的字符的值不能算在内

//561MS 3400K 3373 B 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

#define RR(x) (x<<1|1)
#define LL(x) (x<<1)
const int M =50000+5000;
int n,m;
char str[M];
int rts[M];//每个字符位置对应线段树根结点的位置
struct node
{
    int l,r;
    int sum;
    int mid()
    {
        return (l+r)>>1;
    }
};
inline bool ok(int pos)
{
    return (str[pos]=='b'&&str[pos-1]=='w'&&str[pos+1]=='w');
}
struct Segtree
{
    node tree[M<<2];
    void up(int rt)
    {
        tree[rt].sum=tree[LL(rt)].sum+tree[RR(rt)].sum;
    }
    void build(int l,int r,int rt)
    {
        tree[rt].l = l;
        tree[rt].r = r;
        if(l==r)
        {
            rts[l]=rt;
            if(l==0||l==n-1) tree[rt].sum=0;
            else tree[rt].sum = ok(l);
            return ;
        }
        int mid=tree[rt].mid();
        build(l,mid,LL(rt));
        build(mid+1,r,RR(rt));
        up(rt);
    }
    void update(int pos,char ch,int rt)
    {
        if(tree[rt].l==tree[rt].r)
        {
            str[pos]=ch;
            if(pos==0||pos==n-1) tree[rt].sum=0;
            else tree[rt].sum= ok(pos);
            return ;
        }
        int mid=tree[rt].mid();
        if(pos<=mid) update(pos,ch,LL(rt));
        else update(pos,ch,RR(rt));
        up(rt);
    }
    int query(int L,int R,int rt)
    {
        if(L<=tree[rt].l&&tree[rt].r<=R)
        {
            int tmp=0;
            if(L==tree[rt].l&&tree[rts[L]].sum) tmp++;
            if(R==tree[rt].r&&tree[rts[R]].sum) tmp++;
            if(L==R) tmp=tree[ rts[R] ].sum ;
            return tree[rt].sum-tmp;
        }
        int sum=0;
        int mid=tree[rt].mid();
        if(L<=mid) sum+=query(L,R,LL(rt));
        if(R>mid) sum+=query(L,R,RR(rt));
        return sum;
    }
}seg;
int main()
{
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        printf("Case %d:\n",cas);
        scanf("%d%d",&n,&m);
        scanf("%s",str);

        seg.build(0,n-1,1);
        while(m--)
        {
            int op;
            scanf("%d",&op);
            if(op==0)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%d\n",seg.query(l,r,1));
            }
            else
            {
                int p;
                char ch;
                scanf("%d %c",&p,&ch);
                seg.update(p,ch,1);
                if(p-1>0) seg.update(p-1,str[p-1],1);
                if(p+1<n-1) seg.update(p+1,str[p+1],1);
 
            }
        }
    }
    return 0;
}


HDU 4046 Panda(线段树)

标签:

原文地址:http://blog.csdn.net/kalilili/article/details/44171539

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!