【模板】超级线段树set操作

#include<bits/stdc++.h>
using namespace std;
int add_mark[400010];
int set_mark[400010];
struct node
{
	int max,min,sum;
}tree[400010];
int a[400010];
void push_mark(int x,int l,int r)
{
    int mid=(l+r)>>1;
    if(set_mark[x]!=-2139062144)
    {
        add_mark[x]=0;
        tree[x<<1].max=set_mark[x];
        tree[x<<1].min=set_mark[x];
        tree[x<<1].sum=set_mark[x]*(mid-l+1);
        tree[x<<1|1].max=set_mark[x];
        tree[x<<1|1].min=set_mark[x];
        tree[x<<1|1].sum=set_mark[x]*(r-mid);
        set_mark[x<<1]=set_mark[x];
        set_mark[x<<1|1]=set_mark[x];
        set_mark[x]=-1;
    }
    if(add_mark[x])
    {
        tree[x<<1].max+=add_mark[x];
        tree[x<<1].min+=add_mark[x];
        tree[x<<1].sum+=add_mark[x]*(mid-l+1);
        tree[x<<1|1].max+=add_mark[x];
        tree[x<<1|1].min+=add_mark[x];
        tree[x<<1|1].sum+=add_mark[x]*(r-mid);
        add_mark[x<<1]+=add_mark[x];
        add_mark[x<<1|1]+=add_mark[x];
        add_mark[x]=0;
    }
    return;
}
void updata(int x)
{
    tree[x].max=max(tree[x<<1].max,tree[x<<1|1].max);
    tree[x].min=min(tree[x<<1].min,tree[x<<1|1].min);
    tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
    return;
}
node build_tree(int x,int l,int r)
{
    if(l==r)
    {
        tree[x].max=a[l];
        tree[x].min=a[l];
        tree[x].sum=a[l];
        return tree[x];
    }
    int mid=(l+r)>>1;
    tree[x].max=max(build_tree(x<<1,l,mid).max,build_tree(x<<1|1,mid+1,r).max);
    tree[x].min=min(build_tree(x<<1,l,mid).min,build_tree(x<<1|1,mid+1,r).min);
    tree[x].sum=build_tree(x<<1,l,mid).sum+build_tree(x<<1|1,mid+1,r).sum;
    return tree[x];
}
void do_set(int x,int l,int r,int a,int b,int val)
{
    push_mark(x,l,r);
    if(a<=l&&b>=r)
    {
        tree[x].max=val;
        tree[x].min=val;
        tree[x].sum=val*(r-l+1);
        set_mark[x<<1]=val;
        set_mark[x<<1|1]=val;
        return;
    }
    if(b<l||a>r)return;
    int mid=(l+r)>>1;
    do_set(x<<1,l,mid,a,b,val);
    do_set(x<<1|1,mid+1,r,a,b,val);
    updata(x);
    return;
}
void do_add(int x,int l,int r,int a,int b,int val)
{
    push_mark(x,l,r);
    if(a<=l&&b>=r)
    {
        tree[x].max+=val;
        tree[x].min+=val;
        tree[x].sum+=val*(r-l+1);
        add_mark[x<<1]+=val;
        add_mark[x<<1|1]+=val;
        return;
    }
    if(b<l||a>r)return;
    int mid=(l+r)>>1;
    do_add(x<<1,l,mid,a,b,val);
    do_add(x<<1|1,mid+1,r,a,b,val);
    updata(x);
    return;
}
node query(int x,int l,int r,int a,int b)
{
    push_mark(x,l,r);
    if(a<=l&&b>=r)return tree[x];
    if(b<l||a>r)
    {
        node temp;
        temp.max=-1e9;
        temp.min=1e9;
        temp.sum=0;
        return temp;
    }
    int mid=(l+r)>>1;
    node temp;
    temp.max=max(query(x<<1,l,mid,a,b).max,query(x<<1|1,mid+1,r,a,b).max);
    temp.min=min(query(x<<1,l,mid,a,b).min,query(x<<1|1,mid+1,r,a,b).min);
    temp.sum=query(x<<1,l,mid,a,b).sum+query(x<<1|1,mid+1,r,a,b).sum;
    return temp;
}
int main()
{
    int n,m;
    cin>>n>>m;
    memset(add_mark,0,sizeof add_mark);
    memset(add_mark,128,sizeof add_mark);
    for(int i=1;i<=n;i++)
    cin>>a[i];
    build_tree(1,1,n);
    //...
    return 0;
}
0%