数据结构练习
题单 https://www.luogu.com.cn/training/282126#problems
P3372 线段树1
区间加,区间和
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int read() {
int x=0, sg=1; char c=getchar();
while (c!='-'&&!isdigit(c)) c=getchar();
if (c=='-') sg=-1, c=getchar();
while (isdigit(c)) x=x*10+c-'0', c=getchar();
return x*sg;
}
const int N=800005;
int a[N];
struct node {
int l, r;
ll sum, a;
} tr[N];
void build(int x, int l, int r) {
tr[x].l=l; tr[x].r=r;
if (l==r) {
tr[x].sum=a[l];
return;
}
int m=(l+r)/2;
build(2*x, l, m);
build(2*x+1, m+1, r);
tr[x].sum = tr[2*x].sum+tr[2*x+1].sum;
}
void pushdown(int x) {
if (tr[x].l < tr[x].r && tr[x].a) {
tr[2*x].a+=tr[x].a; tr[2*x].sum+=(tr[2*x].r-tr[2*x].l+1)*tr[x].a;
tr[2*x+1].a+=tr[x].a; tr[2*x+1].sum+=(tr[2*x+1].r-tr[2*x+1].l+1)*tr[x].a;
tr[x].a=0;
}
}
void add(int x, int l, int r, ll k) {
if (r<tr[x].l || l>tr[x].r) return ;
if (l<=tr[x].l && tr[x].r<=r) {
tr[x].sum+=(tr[x].r-tr[x].l+1)*k;
tr[x].a+=k;
return ;
}
pushdown(x);
add(2*x, l, r, k);
add(2*x+1, l, r, k);
tr[x].sum = tr[2*x].sum+tr[2*x+1].sum;
}
ll query(int x, int l, int r) {
if (r<tr[x].l || l>tr[x].r) return 0;
if (l<=tr[x].l && tr[x].r<=r) return tr[x].sum;
pushdown(x);
return query(2*x, l, r) + query(2*x+1, l, r);
}
int main() {
int n=read(), m=read();
for (int i=1; i<=n; i++) a[i]=read();
build(1, 1, n);
while (m--) {
int op=read(), x=read(), y=read();
if (op==1) {
add(1, x, y, read());
} else {
printf("%lld\n", query(1, x, y));
}
}
return 0;
}

浙公网安备 33010602011771号