您的位置:首页 > 其它

线段树模板

2018-05-05 17:32 411 查看

 

区间修改,区间查询,求和

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e6+6;
#define LL long long
#define INF 0x7fffffff

int n,q,a[maxn];

struct node{
int l, r;
LL sum, lazy;
void update(int x) {
sum += 1LL*(r-l+1)*x; // 防止爆int
lazy += x;
}
}tree[maxn*4];

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

void push_down(int x) {
int lazy = tree[x].lazy;
if(lazy) {
tree[x<<1].update(lazy);
tree[x<<1|1].update(lazy);
tree[x].lazy = 0;
}
}

void build(int x, int l, int r) {
tree[x].l = l, tree[x].r = r;
tree[x].sum = tree[x].lazy = 0;
if(l == r) {
tree[x].sum = a[l];
}
else {
int mid = (l+r) / 2;
build(x<<1, l, mid);
build(x<<1|1, mid+1, r);
push_up(x);
}
}

void update(int x, int l, int r, int val) {
int L = tree[x].l, R = tree[x].r;
if(l <= L && R <= r) {
tree[x].update(val);
}
else {
push_down(x);
int mid = (L+R) / 2;
if(mid >= l) update(x<<1, l, r, val);
if(r > mid) update(x<<1|1, l, r, val);
push_up(x);
}
}

LL query(int x, int l, int r) {
int L = tree[x].l, R = tree[x].r;
if(l <= L && R <= r) return tree[x].sum;
else {
push_down(x);
int mid = (L+R) / 2;
LL ans = 0;
if(mid >= l) ans += query(x<<1, l, r);
if(r > mid) ans += query(x<<1|1, l, r);
push_up(x);
return ans;
}
}

int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++)a[i]=0;
build(1,1,n);
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int o,l,r,val;
scanf("%d%d%d%d",&o,&l,&r,&val);
if(o==0)update(1,l,r,val);
else printf("%lld\n",query(1,l,r));
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: