线段树单点更新,区间求和、求最值 模板(区间更新的模板待续)

单点更新分为两种,①把某个值改成另一个值   ②把某个值加上一个值  具体视情况而定,,代码里有说明。

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn = 2e5;     //点的个数
struct Point_Segtree      //单点更新,区间求和,求最值
{
    int seg[maxn<<2],sum[maxn<<2],maxv[maxn<<2],minv[maxn<<2];
    void push_down(int pos)
    {
        sum[pos] = sum[pos<<1] + sum[pos<<1|1];
        minv[pos] = min(minv[pos<<1],minv[pos<<1|1]);
        maxv[pos] = max(maxv[pos<<1],maxv[pos<<1|1]);
    }
    void build(int l,int r,int pos)
    {
        if (l == r)
        {
            scanf ("%d",seg+pos);
            maxv[pos] = minv[pos] = sum[pos] = seg[pos];
            return;
        }
        int mid = (l + r) >> 1;
        build(l,mid,pos<<1);
        build(mid+1,r,pos<<1|1);
        push_down(pos);
    }
    void update(int l,int r,int pos,int x,int v)         //修改  位置为x 的值,
    {
        if (l == r)
        {
            seg[pos] = v;        // 修改时,直接把某个值改为 v
            seg[pos] += v;      // 修改时,把某个值加上 v    二者选一
            sum[pos] = seg[pos];
            minv[pos] = seg[pos];
            maxv[pos] = seg[pos];
        }
        else
        {
            int mid = (l + r) >> 1;
            if (x <= mid)
                update(l,mid,pos<<1,x,v);
            else
                update(mid+1,r,pos<<1|1,x,v);
			push_down(pos);
        }
    }
    int _sum,_min,_max;
    void init()          //每次查询都要初始化一下。
    {
    	_sum = 0;
    	_max = -100000000;
    	_min = 100000000;
    }
    void query(int l,int r,int pos,int ua,int ub)           //[ua, ub]为要查询的区间
    {
    	if (ua <= l && ub >= r)
		{
			_sum += sum[pos];
			_min = min(_min,minv[pos]);
			_max = max(_max,maxv[pos]);
			return;
		}
		int mid = (l + r) >> 1;
		if (ua <= mid)
			query(l,mid,pos<<1,ua,ub);
		if (ub > mid)
			query(mid+1,r,pos<<1|1,ua,ub);
    }
};
int main(void)
{
	return 0;
}

  

原文地址:https://www.cnblogs.com/oneshot/p/3986382.html