线段树做法,为啥全RE
查看原帖
线段树做法,为啥全RE
749201
zhu_wen楼主2023/12/17 18:56
// Problem: P3374 【模板】树状数组 1
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3374
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

#define ls (rt << 1)
#define rs ((rt << 1) | 1)
#define mid (l+r)>>1
#define fst ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int N = 1e6 + 10, M = 2e6 + 10;
  
il ll read() { re ll x = 0; re bool f = true; re char c = getchar(); while (c < 48 || c > 57) { (c == '-') ? f = false : 0; c = getchar(); } while (c > 47 && c < 58) x = (x << 3) + (x << 1) + c - 48, c = getchar(); return f ? x : -x; }

int n,m,a[N];
struct node
{
	int l,r;
	int sum;
};
node tr[N<<2];
void pushup(int rt)
{
	tr[rt].sum=tr[ls].sum+tr[rs].sum;
}
void build(int rt, int l, int r)
{
	tr[rt] = {l, r, 0};	
	if(l == r)
	{
		tr[rt].sum = a[l];
		return;
	}
	build(ls, l, mid);	//处理左儿子
	build(rs, mid+1, r);	//处理有儿子
	pushup(rt);	//向上传递
}
void print(int rt)
{
	int l=tr[rt].l;
	int r=tr[rt].r;
	if(l==r)
	{
		return ;
	}
	print(ls);
	print(rs);
}
void update(int rt,int p,int v)
{
	int l=tr[rt].l;
	int r=tr[rt].r;
	if(l==r)
	{
		tr[rt].sum+=v;
		return ;
	}
	if(p<=mid)
	{
		update(ls,p,v);
	}
	if(p>mid)
	{
		update(rs,p,v);
	}
	pushup(rt);
}
node query(int rt,int sp,int ep)
{
	int l=tr[rt].l;
	int r=tr[rt].r;
	if(sp<=l&&r<=ep)
	{
		return tr[rt];
	}
	if(ep<=mid)
	{
		return query(ls,sp,ep);
	}
	if(sp>mid)
	{
		return query(rs,sp,ep);
	}
	auto L=query(ls,sp,ep);
	auto R=query(rs,sp,ep);
	node res;
	res.l=L.l;
	res.r=R.r;
	res.sum=L.sum+R.sum;
	return res;
}

signed main()
{	fst;
	n=read(),m=read();
	fup(i,1,n)
	{
		a[i]=read();
	}
	build(1,1,n); //构建一棵以1为根节点,管辖范围为[1,n]的数
	while(m--)
	{
		int op,x,y;
		cin>>op>>x>>y;
		if(op==1)
		{
			update(1,x,y);
		}
		else
		{
			auto res=query(1,x,y);
			cout<<res.sum<<endl;
		}
	}
	return 0;
}

2023/12/17 18:56
加载中...