您的位置:首页 > 其它

洛谷3372 线段树1

2017-08-07 21:02 232 查看
//注意求和要*区间个数
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, m;
long long a[maxn];

struct node{
long long val, mark;
} segtree[4*maxn];

inline void make_tree(int root, int l, int r){
segtree[root].mark = 0;
if(l == r){
segtree[root].val = a[l];
return;
}
int mid = l+r >> 1;
make_tree(root*2, l, mid);
make_tree(root*2+1, mid+1, r);
segtree[root].val = segtree[root*2].val + segtree[root*2+1].val;
}

inline void pushdown(int root, int l, int r){
if(segtree[root].mark){
int mid = l+r >> 1;
segtree[2*root].mark += segtree[root].mark;
segtree[2*root+1].mark += segtree[root].mark;
segtree[2*root].val += segtree[root].mark * (mid-l+1);
segtree[2*root+1].val += segtree[root].mark * (r-mid);
segtree[root].mark = 0;
}
}

inline void update(int root, int nl, int nr, int l, int r, int k){
if(nl > r || nr < l)    return;
if(nl >= l && nr <= r){
segtree[root].mark += k;
segtree[root].val += (nr-nl+1) * k;
return;
}
pushdown(root, nl, nr);
int mid = nl+nr >> 1;
update(root*2, nl, mid, l, r, k);
update(root*2+1, mid+1, nr, l, r, k);
segtree[root].val = segtree[2*root].val + segtree[2*root+1].val;
}

inline long long get_sum(int root, int nl, int nr, int l, int r){
long long ans = 0;
//if(nl > r || nr < l)    return 0;
//if(nl == nr)    return segtree[root].val;
if(nl >= l && nr <= r)    return segtree[root].val;
pushdown(root, nl, nr);
int mid = nl+nr >> 1;
if(mid < r)    ans += get_sum(root*2+1, mid+1, nr, l, r);
if(mid >= l)    ans += get_sum(root*2, nl, mid, l, r);
return ans;
}

int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
make_tree(1, 1, n);
for(int i = 1, op, x, y, k; i <= m; i++){
scanf("%d", &op);
if(op == 1){
scanf("%d%d%d", &x, &y, &k);
update(1, 1, n, x, y, k);
}
else if(op == 2){
scanf("%d%d", &x, &y);
long long sum = get_sum(1, 1, n, x, y);
//printf("%lld\n", segtree[1].val);
printf("%lld\n", sum);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: