线段树模板

线段树模板

单点修改 区间查询模板

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;
const int N = 100010;

int n , m ;
int w[N];

struct node{
	int l , r , sum;
}tr[N * 4];



void build(int u,int l, int r)
{
	if(l == r){
		tr[u].l = l;tr[u].r = r;
		tr[u].sum = w[r];
	}
	else{
		tr[u].l = l;tr[u].r = r;
		int mid = l + r >> 1;
		build(u << 1,l ,mid);
		build(u << 1 | 1,mid + 1, r);
		tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
	}
}

int query(int u,int l,int r)
{
	if(tr[u].l >= l && tr[u].r <= r)return tr[u].sum;
	int mid = tr[u].l + tr[u].r >> 1;
	int sum = 0;
	if(l <= mid)sum = query(u << 1, l , r);
	if(r > mid) sum += query(u << 1 | 1, l , r);
	return sum;
}

void modify(int u,int x,int v)
{
	if(tr[u].l == tr[u].r)tr[u].sum += v;
	else{
		int mid = tr[u].l + tr[u].r >> 1;
		if(x <= mid)modify(u << 1, x , v);
		else modify(u << 1 | 1,x , v);
		tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
	}
}

int main()
{
	cin >> n >> m;
	// 权值数组必须从1 开始 
	for(int i = 1;i <= n ;i ++)
	{
		scanf("%d",&w[i]);
	}
	
	build(1 , 1 , n);
	
	for(int i = 0;i < m ;i ++)
	{
		int c, x , y;
		cin >> c >> x >> y;
		if(c == 0){
			cout << query(1 , x , y) << endl; 
		}else{
			modify(1 , x, y);
		}
	}
	return 0;
}

区间修改 区间查询

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;
const int N = 100010;

typedef long long ll;

ll n , m ;
ll w[N];

struct node{
	ll l , r , sum , lazy;
}tr[N * 4];


void add(int u,int v)
{
	tr[u].lazy += v;
	tr[u].sum += (tr[u].r - tr[u].l + 1) * v;
	return;
}

void pushdown(int u,int l,int r)
{
	if(tr[u].lazy == 0)return ;
	add(u << 1,tr[u].lazy); //下传左子树 
	add(u << 1 | 1,tr[u].lazy);//下传右子树 
	tr[u].lazy = 0; //取消标记 
}


void build(int u,int l, int r)
{
	if(l == r){
		tr[u].l = l;tr[u].r = r;
		tr[u].sum = w[r];
	}
	else{
		tr[u].l = l;tr[u].r = r;
		int mid = l + r >> 1;
		build(u << 1,l ,mid);
		build(u << 1 | 1,mid + 1, r);
		tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
	}
}

ll query(int u,int l,int r)
{
	if(tr[u].l >= l && tr[u].r <= r)return tr[u].sum;
	int mid = tr[u].l + tr[u].r >> 1;
	ll sum = 0;
	pushdown(u , l , r);
	if(l <= mid)sum = query(u << 1, l , r);
	if(r > mid) sum += query(u << 1 | 1, l , r);
	return sum;
}

void modify(int u,int l, int r,ll v)
{
	if(tr[u].l >= l && tr[u].r <= r)
	{
		return add(u,v);
	}
	int mid = tr[u].l + tr[u].r >> 1;
	pushdown(u , l , r);
	if(l <= mid)modify(u << 1,l , r , v) ;
	if(r > mid) modify(u << 1 | 1,l , r, v);
	tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
} 

int main()
{
	cin >> n >> m;
	// 权值数组必须从1 开始 
	for(int i = 1;i <= n ;i ++)
	{
		scanf("%d",&w[i]);
	} 
	build(1 , 1 , n); 
	int f , x , y , k;
	while(m--)
	{
		cin >> f;
		if(f == 1)
		{
			cin >> x >> y >> k;
			modify(1,x , y , k);
		}else{
			cin >> x >> y;
			cout << query(1,x,y) << endl;
		}
	}
	return 0;
}

posted @ 2020-03-21 10:32  _starsky  阅读(165)  评论(0编辑  收藏  举报