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);
}
}
}