[codevs4927] 线段树练习5

  • 题意(原题):
  • 数列,五种操作,元素与操作个数都是10w。操作为区间加法,区间设为一个值,求区间和,区间最大值区间最小值。
  • 思路:
  • 维护两个lazy,一个add一个set,两个lazy不能共存。
  • 代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
#define MAXN (110000)
#define inf ((LL)999999999999999999)
using namespace std;
struct node
{
    int l,r,mid,ls,rs;
    LL sumVal,minVal,maxVal,setLazy,addLazy;
    node()
    {
        l=r=ls=rs=0;
        sumVal=minVal=maxVal=addLazy=0;
        setLazy=-inf;
    }
}a[MAXN*2];
//setLazyÓëaddLazy²»¹²´æ 
char ss[11];
int len=0,n,m;
LL readVal[MAXN];
//ÕâÁ½¸öº¯ÊýÖ»¹Ü×Ô¼ºÕâ¸öµã 
void treeSetLazy(int x,LL val)
{
    a[x].setLazy=val;
    a[x].addLazy=0;
    a[x].sumVal=val*(a[x].r-a[x].l+1);
    a[x].minVal=val;
    a[x].maxVal=val;
    return ;
}
void treeAddLazy(int x,LL val)
{
    if(a[x].setLazy!=-inf)
    {
        treeSetLazy(x,a[x].setLazy+val);
        return ;
    }
    a[x].addLazy+=val;
    a[x].sumVal+=val*(a[x].r-a[x].l+1);
    a[x].minVal+=val;
    a[x].maxVal+=val;
    return ;
}
void treeUpdate(int x)
{
    if(a[x].l==a[x].r)
    {
        a[x].minVal=a[x].sumVal;
        a[x].maxVal=a[x].sumVal;
        return ;
    }
    a[x].sumVal=a[a[x].ls].sumVal+a[a[x].rs].sumVal;
    a[x].minVal=min(a[a[x].ls].minVal,a[a[x].rs].minVal);
    a[x].maxVal=max(a[a[x].ls].maxVal,a[a[x].rs].maxVal);
    return ;
}
void treeBuild(int l,int r)
{
    int now=++len;
    a[now].l=l;a[now].r=r;a[now].mid=(l+r)/2;
    if(a[now].l==a[now].r)
    {
        a[now].sumVal=readVal[l];
        a[now].minVal=readVal[l];
        a[now].maxVal=readVal[l];
        return ;
    }
    a[now].ls=len+1;
    treeBuild(l,a[now].mid);
    a[now].rs=len+1;
    treeBuild(a[now].mid+1,r);
    treeUpdate(now);
    return ;
}
void treeAdd(int x,int l,int r,int val)
{
    if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r))
    {
        treeAddLazy(x,val);
        return ;
    }
    if(a[x].setLazy!=-inf)
    {
        treeSetLazy(a[x].ls,a[x].setLazy);
        treeSetLazy(a[x].rs,a[x].setLazy);
        a[x].setLazy=-inf;
    }
    if(a[x].addLazy)
    {
        treeAddLazy(a[x].ls,a[x].addLazy);
        treeAddLazy(a[x].rs,a[x].addLazy);
        a[x].addLazy=0;
    }
    if(l<=a[x].mid)treeAdd(a[x].ls,l,min(a[x].mid,r),val);
    if(r>=a[x].mid+1)treeAdd(a[x].rs,max(a[x].mid+1,l),r,val);
    treeUpdate(x);
    return ;
}
void treeSet(int x,int l,int r,int val)
{
    if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r))
    {
        treeSetLazy(x,val);
        return ;
    }
    if(a[x].setLazy!=-inf)
    {
        treeSetLazy(a[x].ls,a[x].setLazy);
        treeSetLazy(a[x].rs,a[x].setLazy);
        a[x].setLazy=-inf;
    }
    if(a[x].addLazy)
    {
        treeAddLazy(a[x].ls,a[x].addLazy);
        treeAddLazy(a[x].rs,a[x].addLazy);
        a[x].addLazy=0;
    }
    if(l<=a[x].mid)treeSet(a[x].ls,l,min(a[x].mid,r),val);
    if(r>=a[x].mid+1)treeSet(a[x].rs,max(a[x].mid+1,l),r,val);
    treeUpdate(x);
    return ;
}
LL treeGetSum(int x,int l,int r)
{
    if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r))
    {
        return a[x].sumVal;
    }
    if(a[x].setLazy!=-inf)
    {
        return a[x].setLazy*(LL)(r-l+1);
    }
    if(a[x].addLazy)
    {
        treeAddLazy(a[x].ls,a[x].addLazy);
        treeAddLazy(a[x].rs,a[x].addLazy);
        a[x].addLazy=0;
    }
    LL ans=0;
    if(l<=a[x].mid)ans+=treeGetSum(a[x].ls,l,min(a[x].mid,r));
    if(r>=a[x].mid+1)ans+=treeGetSum(a[x].rs,max(a[x].mid+1,l),r);
    return ans;
}
LL treeGetMax(int x,int l,int r)
{
    if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r)||(a[x].setLazy!=-inf))
    {
        return a[x].maxVal;
    }
    if(a[x].setLazy!=-inf)
    {
        treeSetLazy(a[x].ls,a[x].setLazy);
        treeSetLazy(a[x].rs,a[x].setLazy);
        a[x].setLazy=-inf;
    }
    if(a[x].addLazy)
    {
        treeAddLazy(a[x].ls,a[x].addLazy);
        treeAddLazy(a[x].rs,a[x].addLazy);
        a[x].addLazy=0;
    } 
    LL ans=-inf;
    if(l<=a[x].mid)ans=max(ans,treeGetMax(a[x].ls,l,min(a[x].mid,r)));
    if(r>=a[x].mid+1)ans=max(ans,treeGetMax(a[x].rs,max(a[x].mid+1,l),r));
    return ans;
}
LL treeGetMin(int x,int l,int r)
{
    if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r)||(a[x].setLazy!=-inf))
    {
        return a[x].minVal;
    }
    if(a[x].setLazy!=-inf)
    {
        treeSetLazy(a[x].ls,a[x].setLazy);
        treeSetLazy(a[x].rs,a[x].setLazy);
        a[x].setLazy=-inf;
    }
    if(a[x].addLazy)
    {
        treeAddLazy(a[x].ls,a[x].addLazy);
        treeAddLazy(a[x].rs,a[x].addLazy);
        a[x].addLazy=0;
    } 
    LL ans=inf;
    if(l<=a[x].mid)ans=min(ans,treeGetMin(a[x].ls,l,min(a[x].mid,r)));
    if(r>=a[x].mid+1)ans=min(ans,treeGetMin(a[x].rs,max(a[x].mid+1,l),r));
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",&readVal[i]);
    treeBuild(1,n); 
    while(m--)
    {
        int x,y,z;
        scanf("%s",ss+1);
        if(ss[2]=='d')
        {
            scanf("%d%d%d",&x,&y,&z);
            treeAdd(1,x,y,z);
        }
        if(ss[2]=='e')
        {
            scanf("%d%d%d",&x,&y,&z);
            treeSet(1,x,y,z);
        }
        if(ss[2]=='u')
        {
            scanf("%d%d",&x,&y);
            printf("%lld\n",treeGetSum(1,x,y));
        }
        if(ss[2]=='a')
        {
            scanf("%d%d",&x,&y);
            printf("%lld\n",treeGetMax(1,x,y));
        }
        if(ss[2]=='i')
        {
            scanf("%d%d",&x,&y);
            printf("%lld\n",treeGetMin(1,x,y));
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值