poj3468 线段树区间求和

本文介绍了一种使用Lazy标记优化线段树的数据结构实现方法。通过延迟更新操作减少重复计算,适用于区间修改和查询问题。文章提供了完整的C++代码示例,展示了如何在大规模数据集上高效地进行区间加法更新和求和查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用Lazy标记,延迟更新,
标记如果不开long long 就会WA  

我计算了一下,10W*10W是超int

	#include <map>
	#include <queue>
	#include <stack>
	#include <deque>
	#include <math.h>
	#include <string>
	#include <vector>
	#include <stdio.h>
	#include <iostream>
	#include <string.h>
	#include <algorithm>
	#include <functional>
	#define mem(a) memset(a,0,sizeof(a));
	#define mem_1(a) memset(a,-1,sizeof(a));
	#define sf(a) scanf("%d",&a)
	#define lson l,mid,i<<1
	#define rson mid+1,r,i<<1|1
	#define sff(a,b) scanf("%d%d",&a,&b)
	#define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c)
	#define LL long long
	const int INF = 0x7FFFFFFF;
	const int MAXN = 100100;
	const double PI = acos(-1.0);
	const double esp = 1e-10;
	using namespace std;
	struct node
	{
		int l,r;
		LL sum,num,lazy;
		int mid(){return (l+r) >>1 ;}
	}Tree[MAXN << 2];
	void pushUp(int i)
	{
		Tree[i].sum = Tree[i<<1].sum + Tree[i<<1|1].sum;
	}
	void pushDown(int i)
	{
		if(Tree[i].lazy)
		{
			Tree[i<<1].lazy += Tree[i].lazy;
			Tree[i<<1|1].lazy += Tree[i].lazy;
			Tree[i<<1].sum += (Tree[i<<1].r - Tree[i<<1].l +1) * Tree[i].lazy;
			Tree[i<<1|1].sum += (Tree[i<<1|1].r - Tree[i<<1|1].l+1) * Tree[i].lazy;
			Tree[i].lazy = 0;
		}
	}
	void B_tree(int l,int r,int i)
	{
		Tree[i].l = l;
		Tree[i].r = r;
		Tree[i].lazy = 0;
		if(l == r)
		{
			scanf("%lld",&Tree[i].num);
			Tree[i].sum = Tree[i].num;
			return ;
		}
		int mid = (l+r)>>1;
		B_tree(lson);
		B_tree(rson);
		pushUp(i);
	}
	void updata_tree(int l,int r,int i,LL k)
	{
		if(Tree[i].l ==l && r == Tree[i].r)
		{
			Tree[i].lazy += k;
			Tree[i].sum += ((LL)(Tree[i].r - Tree[i].l +1))*k;
			return ;
		}
		pushDown(i);
		int mid = Tree[i].mid();
		if(r <= mid) updata_tree(l,r,i<<1,k);
		else if(mid < l) updata_tree(l,r,i<<1|1,k);
		else
		{
			updata_tree(lson,k);
			updata_tree(rson,k);
		}
		pushUp(i);
	}
	LL Query(int l,int r,int i)
	{
		if(Tree[i].l == l && Tree[i].r == r)
		{
			return Tree[i].sum;
		}
		pushDown(i);
		int mid = Tree[i].mid();
		if(r<=mid) return  Query(l,r,i<<1);
		else if(mid < l) return Query(l,r,i<<1|1);
		else
		{
			return Query(lson) + Query(rson);
		}
	}
	int main()
	{
		int n,m;
		char c;
		int form,to;
		sff(n,m);
		B_tree(1,n,1);
		while(m--)
		{
			cin >> c;
			if(c=='Q')
			{
				sff(form,to);
				updata_tree(form,to,1,0);
				printf("%lld\n",Query(form,to,1));
			}
			else
			{
				LL K;
				sff(form,to);
				scanf("%lld",&K);
				updata_tree(form,to,1,K);
			}
		}
		return 0;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值