求助线段树,样例过不了(有注释)
查看原帖
求助线段树,样例过不了(有注释)
804607
rainygame楼主2023/3/22 20:12

RT。刚学不到几小时,不知道哪里写错了……

#include <bits/stdc++.h>
using namespace std;
#define MAXN 500001

int n, m, x, y, opt;
long long k;
long long a[MAXN];

struct Tree{  // 线段树结点 
	int l, r;
	long long sum;
}tree[MAXN<<2];  // 注意要开到4倍空间 

void build(int l, int r, int p){  // 建线段树
	tree[p].l = l;  // 定义左边界 
	tree[p].r = r;  // 定义右边界
	if (l == r){  // 如果[l,r]为一个单点
		tree[p].sum = a[l];  // 则它的权值为那个单点的数 
		return;
	}
	
	int mid = (l+r)>>1;
	build(l, mid, p<<1);  // 递归查找左右儿子 
	build(mid+1, r, (p<<1)+1);
	
	tree[p].sum = tree[p<<1].sum + tree[(p<<1)+1].sum;  // 即为左右儿子的权值之和 
}

void add(int l, int r, long long k, int p){  // [l,r]加上k,现在搜到了p 
	if (tree[p].l >= l && tree[p].r <= r){  // 完全在区间内 
		tree[p].sum += k;
		return;
	}
	if (tree[p<<1].r >= l) add(l, r, k, p<<1);  // 递归左儿子 
	if (tree[(p<<1)+1].l <= r) add(l, r, k, (p<<1)+1);  // 递归右儿子 
}

long long query(int i, int p){  // 查询单点i的值 
	long long ans = tree[p].sum;
	if (tree[p].l == tree[p].r) return ans;  // 单点 
	if (i <= tree[p<<1].r) ans += query(i, p<<1);  // 递归左儿子 
	if (i >= tree[(p<<1)+1].l) ans += query(i, (p<<1)+1);  // 递归右儿子 
	return ans;  // 返回 
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin >> n >> m;
	for (int i=1; i<=n; i++) cin >> a[i];
	build(1, n, 1);
	
	while (m--){
		cin >> opt;
		if (opt == 1){  // 区间修改
			cin >> x >> y >> k;
			add(x, y, k, 1);
		}else{  // 单点查询
			cin >> x;
			cout << query(x, 1) << '\n';
		}
	}
	
	return 0;
}

2023/3/22 20:12
加载中...