zoukankan      html  css  js  c++  java
  • 哈理工OJ1524最大

    线段树题目,给出一个序列,查询一段a,b之间的最大的连续相同的数字的和最大是多少,定义为MS,因为对于一个区间的MS,可能来自于左子节点或者右子节点,或者当左节点最右面的数字和右节点的左面的数字相同时可能会来自两个节点合并的部分,所以,树中的节点要维护五个基本的值,lval(最左侧的值),lnum(最左侧值连续的个数),rval(最右侧的值),rnum(最右侧值连续的个数)以及MS,为了提高效率,还要增加一个标记值,不需要更新每一个节点。

    View Code
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 100005
    #define L(x) x<<1
    #define R(x) x<<1|1
    using namespace std;
    int val[N];
    int max(int a,int b)
    {
        return a>b?a:b;
    }
    int min(int a,int b)
    {
        return a<b?a:b;
    }
    struct node
    {
        int l,r;
        int lval,rval;
        int lnum,rnum;
        int Ms;
        int f;
    };
    node tree[4*N];
    void build(int l,int r,int i)
    {
        tree[i].l=l;
        tree[i].r=r;
        tree[i].f=-1;//初始化为-1,更新的值有可能是0
        tree[i].Ms=0;
        if(l==r)
        {
            tree[i].lval=tree[i].rval=tree[i].Ms=tree[i].f=val[l];
            tree[i].lnum=tree[i].rnum=1;
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,L(i));
        build(mid+1,r,R(i));
        tree[i].lval=tree[L(i)].lval;
        tree[i].rval=tree[R(i)].rval;
        if(tree[L(i)].lnum==mid-l+1&&tree[R(i)].lval==tree[L(i)].lval)
        tree[i].lnum=tree[L(i)].lnum+tree[R(i)].lnum;
        else
        tree[i].lnum=tree[L(i)].lnum;
        if(tree[R(i)].rnum==r-mid&&tree[L(i)].rval==tree[R(i)].rval)
        tree[i].rnum=tree[R(i)].rnum+tree[L(i)].rnum;
        else
        tree[i].rnum=tree[R(i)].rnum;
        tree[i].Ms=max(tree[L(i)].Ms,tree[R(i)].Ms);
        if(tree[L(i)].rval==tree[R(i)].lval)
        tree[i].Ms=max(tree[i].Ms,tree[L(i)].rval*(tree[L(i)].rnum+tree[R(i)].lnum));
    }
    void update(int l,int r,int v,int i)
    {
        if(tree[i].l==l&&tree[i].r==r)
        {
            tree[i].lval=tree[i].rval=v;
            tree[i].lnum=tree[i].rnum=r-l+1;
            tree[i].f=v;
            tree[i].Ms=(r-l+1)*v;
            return;
        }
        if(tree[i].f!=-1)
        {
            tree[L(i)].lval=tree[L(i)].rval=tree[i].f;
            tree[R(i)].lval=tree[R(i)].rval=tree[i].f;
            tree[L(i)].lnum=tree[L(i)].rnum=tree[L(i)].r-tree[L(i)].l+1;
            tree[R(i)].lnum=tree[R(i)].rnum=tree[R(i)].r-tree[R(i)].l+1;
            tree[L(i)].Ms=tree[L(i)].lval*tree[L(i)].lnum;
            tree[R(i)].Ms=tree[R(i)].lval*tree[R(i)].lnum;
            tree[L(i)].f=tree[R(i)].f=tree[i].f;
            tree[i].f=-1;
        }
        int mid=(tree[i].l+tree[i].r)>>1;
        if(r<=mid)
        update(l,r,v,L(i));
        else if(l>mid)
        update(l,r,v,R(i));
        else
        {
            update(l,mid,v,L(i));
            update(mid+1,r,v,R(i));
        }
        tree[i].lval=tree[L(i)].lval;
        tree[i].rval=tree[R(i)].rval;
        if(tree[L(i)].lnum==mid-tree[i].l+1&&tree[R(i)].lval==tree[L(i)].lval)
        tree[i].lnum=tree[L(i)].lnum+tree[R(i)].lnum;
        else
        tree[i].lnum=tree[L(i)].lnum;
        if(tree[R(i)].rnum==tree[i].r-mid&&tree[L(i)].rval==tree[R(i)].rval)
        tree[i].rnum=tree[R(i)].rnum+tree[L(i)].rnum;
        else
        tree[i].rnum=tree[R(i)].rnum;
        tree[i].Ms=max(tree[L(i)].Ms,tree[R(i)].Ms);
        if(tree[L(i)].rval==tree[R(i)].lval)
        tree[i].Ms=max(tree[i].Ms,tree[L(i)].rval*(tree[L(i)].rnum+tree[R(i)].lnum));
    }
    int query(int l,int r,int i)
    {
        if(tree[i].l==l&&tree[i].r==r)
        {
            return tree[i].Ms;
        }
        int ans1,ans2,ans3;
        ans1=ans2=ans3=0;
        if(tree[i].f!=-1)
        {
            tree[L(i)].lval=tree[L(i)].rval=tree[i].f;
            tree[R(i)].lval=tree[R(i)].rval=tree[i].f;
            tree[L(i)].lnum=tree[L(i)].rnum=tree[L(i)].r-tree[L(i)].l+1;
            tree[R(i)].lnum=tree[R(i)].rnum=tree[R(i)].r-tree[R(i)].l+1;
            tree[L(i)].Ms=tree[L(i)].lval*tree[L(i)].lnum;
            tree[R(i)].Ms=tree[R(i)].lval*tree[R(i)].lnum;
            tree[L(i)].f=tree[R(i)].f=tree[i].f;
            tree[i].f=-1;
        }
        int mid=(tree[i].l+tree[i].r)>>1;
        if(r<=mid)
        ans1=query(l,r,L(i));
        else if(l>mid)
        ans2=query(l,r,R(i));
        else
        {
            ans1=query(l,mid,L(i));
            ans2=query(mid+1,r,R(i));
            if(tree[L(i)].rval==tree[R(i)].lval)
            ans3=tree[L(i)].rval*(min(tree[L(i)].rnum,mid-l+1)+min(tree[R(i)].lnum,r-mid));
        }
        //printf("%d %d %d %d %d %d\n",l,r,i,ans1,ans2,ans3);
        ans1=max(ans1,ans2);
        ans1=max(ans1,ans3);
        return ans1;
    }
    int main()
    {
        int n,m,i,j;
        int icase=0;
        int op,a,b,c;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=1;i<=n;i++)
            scanf("%d",&val[i]);
            build(1,n,1);
            printf("Case %d:\n",++icase);
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d",&op);
                if(op==1)
                {
                    scanf("%d%d%d",&a,&b,&c);
                    update(a,b,c,1);
                }
                else
                {
                    scanf("%d%d",&a,&b);
                    printf("%d\n",query(a,b,1));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    长沙集训day6
    长沙集训day5(总结)
    长沙集训day4(总结)(爆零记)
    长沙集训day3(总结)(爆零记)
    长沙集训day2(总结)
    长沙集训day1(总结)
    p1324 dining(晚餐)
    p1156集合删数
    1034: [ZJOI2008]泡泡堂BNB
    清北学堂Day 6 游记
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2636656.html
Copyright © 2011-2022 走看看