NCSTOJ:A Simple Problem with Integers

C : [算法竞赛进阶指南]A Simple Problem with Integers
Time Limit:2 Sec Memory Limit:128 MiB
Back Submit Edit

Description
[poj 3468]

给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:
1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。

2、“Q l r”,表示询问 数列中第 l~r 个数的和。

对于每个询问,输出一个整数表示答案。

Input
第一行两个整数N,M。

第二行N个整数A[i]。

接下来M行表示M条指令,每条指令的格式如题目描述所示。

数据范围
1≤N,M≤10^5,

|d|≤10000,

|A[i]|≤1000000000

Output
对于每个询问,输出一个整数表示答案。

每个答案占一行。

Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15

#include<iostream>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 10;

int n, m;
int a[maxn], s[maxn], c[maxn]; // a为原数组,s为前缀和数组,c为树状数组

inline int lowbit(int x) { return x & -x; }
int ask(int x)
{
	int ans=0;
	for(;x;x-=lowbit(x))
	ans+=c[x];
	return ans;
	
}
void add(int x,int y)
{
	for(;x<=n;x+=lowbit(x))
	c[x]+=y;
}
int main(){
	//freopen("qwe.txt","r",stdin);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	a[i]+=a[i-1];
	}
	
	while(m--)
	{
		char k[2];
		scanf("%s",k);
		if(k[0]=='Q')
		{
			int k1,k2;
			scanf("%d %d",&k1,&k2);
			printf("%d\n",(a[k2]+ask(k2))-(a[k1-1]+ask(k1-1)));
			
		}
		if(k[0]=='C')
		{
			int k1,k2,k3;
			scanf("%d %d %d",&k1,&k2,&k3);
			for(int i=k1;i<=k2;i++)
			add(i,k3);
			
		}
		
		
	}
	
	
	
}

你可能感兴趣的:(树状数组,线段树)