ISTP @ 2024-03-12 19:19:35
在学动态开点,题面样例和手搓的小样例都过了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct stn{
long long sum, lz_add;
stn* lp;
stn* rp;
};
long long a[maxn];
int n, m;
int cnt;
void build(int, int, stn*);
void update(int, int, int, int, long long, stn*);
long long query(int, int, int, int, stn*);
void push_down(int, int, stn*);
void push_up(stn*);
void check(stn*&);
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i ++)
cin >> a[i];
stn root;
stn* rootp = &root;
build(1, n, rootp);
while(m --){
int opr, x, y;
long long k;
cin >> opr;
if(opr == 1){
cin >> x >> y >> k;
update(1, n, x, y, k, rootp);
}
else{
cin >> x >> y;
cout << query(1, n, x, y, rootp) << '\n';
}
}
return 0;
}
void check(stn* &p){
if(p == nullptr){
stn* childp = new stn;
p = childp;
}
return ;
}
void build(int lf, int rt, stn* p){
p->sum = p->lz_add = 0;
p->lp = p->rp = nullptr;
if(lf == rt){
p->sum = a[lf];
return ;
}
check(p->lp), check(p->rp);
int mid = lf + rt >> 1;
build(lf, mid, p->lp), build(mid + 1, rt, p->rp);
push_up(p);
return ;
}
void push_down(int lf, int rt, stn* p){
int mid = lf + rt >> 1;
p->lp->sum += p->lz_add * (mid - lf + 1);
p->lp->lz_add += p->lz_add;
p->rp->sum += p->lz_add * (rt - mid);
p->rp->lz_add += p->lz_add;
p->lz_add = 0;
return ;
}
void push_up(stn* p){
p->sum = p->lp->sum + p->rp->sum;
return;
}
void update(int lf, int rt, int s, int t, long long val, stn* p){
if(lf == s && rt == t){
p->sum += val, p->lz_add += val;
return ;
}
check(p->lp), check(p->rp);
push_down(lf, rt, p);
int mid = lf + rt >> 1;
if(t <= mid) update(lf, mid, s, t, val, p->lp);
else if(mid < s) update(mid + 1, rt, s, t, val, p->rp);
else update(lf, mid, s, mid, val, p->lp), update(mid + 1, rt, mid + 1, t, val, p->rp);
push_up(p);
return ;
}
long long query(int lf, int rt, int s, int t, stn* p){
if(lf == s && rt == t) return p->sum;
check(p->lp), check(p->rp);
push_down(lf, rt, p);
int mid = lf + rt >> 1;
if(t <= mid) return query(lf, mid, s, t, p->lp);
else if(mid < s) return query(mid + 1, rt, s, t, p->rp);
else return query(lf, mid, s, mid, p->lp) + query(mid + 1, rt, mid + 1, t, p->rp);
}
by ISTP @ 2024-03-12 19:48:19
自查出来了,update
函数里更新写忘乘区间长度了。
if(lf == s && rt == t){
p->sum += val, p->lz_add += val;
return ;
}
应该是
if(lf == s && rt == t){
p->sum += val * (rt - lf + 1), p->lz_add += val;
return ;
}
此帖结。