AcWing 1264 线段树解法

线段树的单点修改和区间查询

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int n, m;
int w[N];
struct node{
	int l, r;
	
	int sum;
}tr[N * 4];

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

void build(int u, int l, int r){
	if(l == r) tr[u] = {l, r, w[r]};
	else{
		tr[u] = {l, r};
		int mid = l + r >> 1;
		build(u << 1, l, mid);
		build(u << 1| 1, mid + 1, r);
		push_up(u);
	}
}

int query(int u, int l, int r){
	if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;	
	int res = 0;
	int mid = tr[u].l + tr[u].r >> 1;
	if(l <= mid) res += query(u << 1, l, r);
	if(r > mid) res += query(u << 1 | 1, l, r);
	return res; 	
}

int modify(int u, int x, int v){
	if(tr[u].l == tr[u].r) tr[u].sum += v;
	else{
		int mid = tr[u].l + tr[u].r >> 1;
		if(x <= mid) modify(u << 1, x, v);
		else modify(u << 1 | 1, x, v);
		push_up(u);
	}
}

int main()
{
	cin>>n>>m;
	
	for(int i = 1; i <= n; i ++ ){
		cin>>w[i];
	}
	
	build(1, 1, n);
	
	while(m -- ){
		int k, a, b;
		cin>>k>>a>>b;
		if(!k) cout<<query(1, a, b)<<endl;
		else modify(1, a, b);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是acwing模板线段树的示例代码: ```cpp const int N = 100010; int n, m; int a[N]; struct Node { int l, r; int v, lazy; } tree[N * 4]; void pushup(int x) { tree[x].v = tree[x * 2].v + tree[x * 2 + 1].v; } void pushdown(int x) { if (tree[x].lazy) { int l = tree[x].l, r = tree[x].r; int mid = (l + r) >> 1; tree[x * 2].v += tree[x].lazy * (mid - l + 1); tree[x * 2 + 1].v += tree[x].lazy * (r - mid); tree[x * 2].lazy += tree[x].lazy; tree[x * 2 + 1].lazy += tree[x].lazy; tree[x].lazy = 0; } } void build(int x, int l, int r) { tree[x].l = l, tree[x].r = r; if (l == r) { tree[x].v = a[l]; return; } int mid = (l + r) >> 1; build(x * 2 l, mid); build(x * 2 + 1, mid +1, r); pushup(x); } void modify(int x, int l, int r, int val) { if (tree[x].l >= l && tree[x].r <= r) { tree[x].v += val * (tree[x].r - tree[x].l + 1); tree[x].lazy += val; return; } pushdown(x); int mid = (tree[x].l + tree[x].r) >> 1; if (l <= mid) modify(x * 2, l, r, val); if (r > mid) modify(x * 2 + 1, l, r, val); pushup(x); } int query(int x, int l, int r) { if (tree[x].l >= l && tree[x].r <= r) { return tree[x].v; } pushdown(x); int mid = (tree[x].l + tree[x].r) >> 1; int sum = 0; if (l <= mid) sum += query(x * 2, l, r); if (r > mid) sum += query(x * 2 + 1, l, r); return sum; } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i]; } build(1, 1, n); while (m--) { int op, l, r, val; cin >> op; if (op == 1) { cin >> l >> r >> val; modify(1, l, r, val); } else if (op == 2) { cin >> l >> r; cout << query(1, l, r) << endl; } } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值