线段树模板

单点更新,区间求最值


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 222222

using namespace std;

int num[N];

struct Tree
{
    int l;
    int r;
    int max;
} tree[N*4];

void push_up(int root)
{
    tree[root].max=max(tree[root<<1].max,tree[root<<1|1].max);
}

void build(int root,int l,int r)
{
    tree[root].l=l;
    tree[root].r=r;
    if(tree[root].l==tree[root].r)
    {
        tree[root].max=num[l];
        return;
    }
    int mid=(l+r)/2;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
    push_up(root);
}
void update(int root,int pos,int val)
{
    if(tree[root].l==tree[root].r)
    {
        tree[root].max=val;
        return;
    }
    int mid=(tree[root].l+ tree[root].r)/2;
    if(pos<=mid)
        update(root<<1,pos,val);
    else
        update(root<<1|1,pos,val);
    push_up(root);
}
int query(int root,int L,int R)
{
    if(L<=tree[root].l&&R>=tree[root].r)
        return tree[root].max;
    int mid=(tree[root].l+ tree[root].r)/2,ret=0;
    if(L<=mid) ret=max(ret,query(root<<1,L,R));
    if(R>mid) ret=max(ret,query(root<<1|1,L,R));
    return ret;
}


区间更新,区间求和


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 222222

using namespace std;

int num[N];

struct Tree
{
    int l;
    int r;
    long long sum;
    long long col;
} tree[N*4];

void push_up(int rt)
{
    tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
}

void push_down(int rt,int m)
{
    if (tree[rt].col!=0)
    {
        tree[rt<<1].col+=tree[rt].col;
        tree[rt<<1|1].col+=tree[rt].col;
        tree[rt<<1].sum+=(long long)(m-(m/2))*tree[rt].col;
        tree[rt<<1|1].sum+=(long long)(m/2)*tree[rt].col;
        tree[rt].col=0;
    }
}

void build(int root,int l,int r)
{
    tree[root].l=l;
    tree[root].r=r;
    tree[root].col=0;
    if(tree[root].l==tree[root].r)
    {
        tree[root].sum=num[l];
        return;
    }
    int mid=(l+r)/2;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
    push_up(root);
}

void update(int root,int L,int R,int val)
{
    if(L<=tree[root].l&&R>=tree[root].r)
    {
        tree[root].col+=val;
        tree[root].sum+=(long long)val*(tree[root].r-tree[root].l+1);
        return;
    }
    push_down(root,tree[root].r-tree[root].l+1);
    int mid=(tree[root].l+tree[root].r)/2;
    if (L<=mid)
        update(root<<1,L,R,val);
    if (R>mid)
        update(root<<1|1,L,R,val);
    push_up(root);
}


long long query(int root,int L,int R)
{
    if(L<=tree[root].l&&R>=tree[root].r)
        return tree[root].sum;
    push_down(root,tree[root].r-tree[root].l+1);
    int mid=(tree[root].l+ tree[root].r)/2;
    long long ret=0;
    if(L<=mid) ret+=query(root<<1,L,R);
    if(R>mid) ret+=query(root<<1|1,L,R);
    return ret;
}

成段更新,区间求值

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 555555

using namespace std;
const int OO=1e9;
int num[N];
int _min,_max,_sum;

struct Tree
{
    int l;
    int r;
    int max;
    int min;
    int sum;
    int add;
    int set;
}big_tree[N*4];

void push_up(int root,Tree tree[])
{
    tree[root].max=max(tree[root<<1].max,tree[root<<1|1].max);
    tree[root].min=min(tree[root<<1].min,tree[root<<1|1].min);
    tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
}

void push_down(int root,Tree tree[])
{
    if (tree[root].set!=-1)
    {
        if (tree[root].l!=tree[root].r)
        {
            //传递懒惰标记
            tree[root<<1].add=tree[root<<1|1].add=0;
            tree[root<<1].set=tree[root<<1|1].set=tree[root].set;
            //最更新大值
            tree[root<<1].max=tree[root<<1|1].max=tree[root].set;
            //更新最小值
            tree[root<<1].min=tree[root<<1|1].min=tree[root].set;
            //更新区间和
            tree[root<<1].sum=(tree[root<<1].r-tree[root<<1].l+1)*tree[root].set;
            tree[root<<1|1].sum=(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].set;
        }
        tree[root].set=-1;
    }
    if (tree[root].add>0)
    {
        if (tree[root].l!=tree[root].r)
        {
            //传递懒惰标记
            tree[root<<1].add+=tree[root].add;
            tree[root<<1|1].add+=tree[root].add;
            //更新最大值
            tree[root<<1].max+=tree[root].add;
            tree[root<<1|1].max+=tree[root].add;
            //更新最小值
            tree[root<<1].min+=tree[root].add;
            tree[root<<1|1].min+=tree[root].add;
            //更新区间和
            tree[root<<1].sum+=(tree[root<<1].r-tree[root<<1].l+1)*tree[root].add;
            tree[root<<1|1].sum+=(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].add;
        }
        tree[root].add=0;
    }
}

void build(int root,int l,int r,Tree tree[])
{
    tree[root].l=l;
    tree[root].r=r;
    if(tree[root].l==tree[root].r)
    {
        tree[root].max=0;
        tree[root].min=0;
        tree[root].sum=0;
        tree[root].add=0;
        tree[root].set=-1;
        return;
    }
    int mid=(l+r)/2;
    build(root<<1,l,mid,tree);
    build(root<<1|1,mid+1,r,tree);
    push_up(root,tree);
}

void update_add(int root,int L,int R,int val,Tree tree[])
{

    if(L<=tree[root].l&&R>=tree[root].r)
    {
        tree[root].add+=val;
        tree[root].max+=val;
        tree[root].min+=val;
        tree[root].sum+=(tree[root].r-tree[root].l+1)*val;
        return;
    }
    push_down(root,tree);
    int mid=(tree[root].l+tree[root].r)/2;
    if(L<=mid)
        update_add(root<<1,L,R,val,tree);
    if (R>mid)
        update_add(root<<1|1,L,R,val,tree);
    push_up(root,tree);
}

void update_set(int root,int L,int R,int val,Tree tree[])
{
    if(L<=tree[root].l&&R>=tree[root].r)
    {
        tree[root].set=val;
        tree[root].add=0;
        tree[root].max=val;
        tree[root].min=val;
        tree[root].sum=(tree[root].r-tree[root].l+1)*val;
        return;
    }
    push_down(root,tree);
    int mid=(tree[root].l+tree[root].r)/2;
    if(L<=mid)
        update_set(root<<1,L,R,val,tree);
    if (R>mid)
        update_set(root<<1|1,L,R,val,tree);
    push_up(root,tree);
}


void query(int root,int L,int R,Tree tree[])
{
    if(L<=tree[root].l&&R>=tree[root].r)
    {
        _min=min(_min,tree[root].min);
        _max=max(_max,tree[root].max);
        _sum+=tree[root].sum;
        return;
    }
    push_down(root,tree);
    int mid=(tree[root].l+tree[root].r)/2;
    if(L<=mid) query(root<<1,L,R,tree);
    if(R>mid) query(root<<1|1,L,R,tree);
}






原文地址:https://www.cnblogs.com/cyendra/p/3226377.html