• HZAU 1207 Candies(线段树区间查询 区间修改)


    【题目链接】http://acm.hzau.edu.cn/problem.php?id=1207

    【题意】给你一个字符串,然后两种操作:1,将区间L,R更新为A或者B,2,询问区间L,R最长的连续的B为多长。

    【分析】典型线段树,每个节点维护该区间左边连续B的长度,右边连续B的长度,最长的连续B的长度,还有lazy标记。

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <stack>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    typedef long long LL;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    const int N=1e6+10;
    int n,m,k,L,R,V;
    char s[N];
    int lazy[N<<2];
    struct Tree{
        int l,r,maxn,len;
    }a[N<<2];
    void pushdwn(int pos,int len){
        if(lazy[pos]!=-1){
            lazy[pos<<1]=lazy[pos<<1|1]=lazy[pos];
            a[pos<<1].l=a[pos<<1].r=a[pos<<1].maxn=lazy[pos]?len-(len>>1):0;
            a[pos<<1|1].l=a[pos<<1|1].r=a[pos<<1|1].maxn=lazy[pos]?(len>>1):0;
            lazy[pos]=-1;
        }
    }
    void pushup(int pos,int len){
        a[pos].l=a[pos<<1].l;
        a[pos].r=a[pos<<1|1].r;
        if(a[pos].l==len-(len>>1))a[pos].l+=a[pos<<1|1].l;
        if(a[pos].r==(len>>1))a[pos].r+=a[pos<<1].r;
        a[pos].maxn=max(a[pos<<1].r+a[pos<<1|1].l,max(a[pos<<1].maxn,a[pos<<1|1].maxn));
    }
    void build(int pos,int l,int r){
        lazy[pos]=-1;
        if(l==r){
            a[pos].l=a[pos].r=a[pos].maxn=(s[l]=='B')?1:0;
            return;
        }
        int mid=(l+r)>>1;
        build(pos<<1,l,mid);
        build(pos<<1|1,mid+1,r);
        pushup(pos,r-l+1);
    }
    void update(int pos,int l,int r){
        if(L<=l&&r<=R){
            a[pos].l=a[pos].r=a[pos].maxn=V?r-l+1:0;
            lazy[pos]=V;
            return;
        }
        pushdwn(pos,r-l+1);
        int mid=(l+r)>>1;
        if(L<=mid)update(pos<<1,l,mid);
        if(R>mid)update(pos<<1|1,mid+1,r);
        pushup(pos,r-l+1);
    }
    Tree merg(Tree t1,Tree t2){
        Tree ret;
        ret.len=t1.len+t2.len;
        ret.l=t1.l;
        ret.r=t2.r;
        if(t1.l==t1.len) ret.l+=t2.l;
        if(t2.r==t2.len) ret.r+=t1.r;
        ret.maxn=max(t1.r+t2.l,max(t1.maxn,t2.maxn));
        return ret;
    }
    Tree query(int pos,int l,int r){
        if(L<=l&&r<=R){
            a[pos].len=r-l+1;
            return a[pos];
        }
        pushdwn(pos,r-l+1);
        int mid=(l+r)>>1;
        if(mid>=R)return query(pos<<1,l,mid);
        if(mid<L)return query(pos<<1|1,mid+1,r);
        Tree t1=query(pos<<1,l,mid),t2=query(pos<<1|1,mid+1,r);
        return merg(t1,t2);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int cas=1;cas<=t;cas++)
        {
            memset(a,0,sizeof a);
            printf("Case #%d:
    ",cas);
            scanf("%d%d%s",&n,&m,s+1);
            build(1,1,n);
            int p;
            while(m--)
            {
                scanf("%d%d%d",&p,&L,&R);
                if(p==1)
                {
                    scanf("%d",&V);
                    V--;
                    update(1,1,n);
                }
                else printf("%d
    ",query(1,1,n).maxn);
            }
        }
        return 0;
    }
  • 相关阅读:
    线段的平移和旋转
    《构建之法》第一章读书笔记
    课程大作业总结
    2016.1.8
    2016.1.7
    2016.1.6总结
    初学MFC
    实时控制软件第三次编程作业
    实时控制软件设计第二次编程作业
    实时控制软件设计第一次编程作业
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6754620.html
Copyright © 2020-2023  润新知