洛谷 P3368 【模板】树状数组 2

洛谷 P3368 【模板】树状数组 2

洛谷传送门

题目描述

如题,已知一个数列,你需要进行下面两种操作:

  1. 将某区间每一个数数加上 xx
  2. 求出某一个数的值。

输入格式

第一行包含两个整数 NN、MM,分别表示该数列数字的个数和操作的总个数。

第二行包含 NN 个用空格分隔的整数,其中第 ii 个数字表示数列第 ii 项的初始值。

接下来 MM 行每行包含 22 或 44个整数,表示一个操作,具体如下:

操作 11: 格式:1 x y k 含义:将区间 [x,y][x,y] 内每个数加上 kk

操作 22: 格式:2 x 含义:输出第 xx 个数的值。

输出格式

输出包含若干行整数,即为所有操作 22 的结果。


题解:

树状数组维护差分前缀和。

代码:

#include<cstdio>
using namespace std;
const int maxn=5e5+5;
int n,m;
int a[maxn],cf[maxn],tree[maxn];
void update(int x,int k)
{
	for(int i=x;i<=n;i+=i&-i)
		tree[i]+=k;
}
int query(int x)
{
	int ret=0;
	for(int i=x;i;i-=i&-i)
		ret+=tree[i];
	return ret;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		int opt,x,y,k;
		scanf("%d%d",&opt,&x);
		if(opt==1)
		{
			scanf("%d%d",&y,&k);
			update(x,k);
			update(y+1,-k);
		}
		else
			printf("%d
",a[x]+query(x));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/14030825.html