线段树求区间最大值+区间更新+区间求和+lazy标记

马上就省赛了,线段树还缺个求区间最大值的板子,百度,Google全都是一个板子,而且还没有lazy标记,朴素更新,好气啊
区间最小值也同理
lazy的我只能自己写
蓝瘦香菇
code:

#include
#include
#include
#include
#include
#include
#include 
using namespace std;
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
const int eps=1e-8;
const int maxn=30010;//须填写
const int inf=0x3f3f3f3f;
int n,m;
struct node//定义结构体存储线段树
{
    int l;
    int r;
    ll ma;
    ll sum;
    ll mark;
}s[300000];
void pushup(int k)//求和与最大值
{
    s[k].sum=s[k<<1].sum+s[(k<<1)+1].sum;
    s[k].ma=max(s[k<<1].ma,s[(k<<1)+1].ma);
}
void pushdown(int k,int d)//标记下移
{
    if(s[k].mark)
    {
        s[k<<1].mark+=s[k].mark;
        s[(k<<1)+1].mark+=s[k].mark;
        s[k<<1].sum+=s[k].mark*(d-(d>>1));
        //s[k<<1].ma+=s[k].mark;
        s[(k<<1)+1].sum+=s[k].mark*(d>>1);
        //s[(k<<1)+1].ma+=s[k].mark;
        s[k].mark=0;
    }
}
void init(int l,int r,int k)
{
    s[k].l=l;
    s[k].r=r;
    s[k].mark=0;
    s[k].ma=0;
    if(l==r)
    {
        scanf("%lld",&s[k].sum);
        s[k].ma=s[k].sum;
        //cout<<"输入成功"<
        return ;
    }
    int mid=(l+r)/2;
    init(l,mid,k<<1);
    init(mid+1,r,(k<<1)+1);
    pushup(k);
}
ll query(int l,int r,int k)
{
    if(l<=s[k].l&&r>=s[k].r)
    {
        return s[k].sum;
    }
    pushdown(k,s[k].r-s[k].l+1);
    int mid=(s[k].l+s[k].r)/2;
    long long  res=0;
    if(l<=mid) res+=query(l,r,(k<<1));
    if(r>mid) res+=query(l,r,(k<<1)+1);
    return res;
}
ll queryma(int l,int r,int k)//查询最大值
{
    if(l<=s[k].l&&r>=s[k].r)
    {
        return s[k].ma;
    }
    pushdown(k,s[k].r-s[k].l+1);
    int mid=(s[k].l+s[k].r)/2;
    long long  resa=0;
    long long  resb=0;
    if(l<=mid) resa=queryma(l,r,(k<<1));
    if(r>mid) resb=queryma(l,r,(k<<1)+1);
    return max(resa,resb);
}
void update(int l,int r,int c,int k)
{
    if(l<=s[k].l&&r>=s[k].r)
    {
        s[k].mark+=c;
        s[k].sum+=(c*(s[k].r-s[k].l+1));
        s[k].ma+=c;
        return ;
    }
    pushdown(k,s[k].r-s[k].l+1);
    int mid=(s[k].l+s[k].r)/2;
    if(l<=mid) update(l,r,c,k<<1);
    if(r>mid) update(l,r,c,(k<<1)+1);
    pushup(k);
}

你可能感兴趣的:(线段树求区间最大值+区间更新+区间求和+lazy标记)