社区讨论

动态开点线段树(指针) WA 0 求助

P3372【模板】线段树 1参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@ltoa8hj9
此快照首次捕获于
2024/03/12 19:21
2 年前
此快照最后确认于
2024/03/12 20:59
2 年前
查看原帖
在学动态开点,题面样例和手搓的小样例都过了。
CPP
#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);
}

回复

1 条回复,欢迎继续交流。

正在加载回复...