线段树模板
单点修改 区间查询模板
#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;
}