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

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

#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;

}

  

你可能感兴趣的:(线段树)