石子总数
Description
有N堆石头摆成一行,第i堆石头有a[i]个,现在我有m次询问,请问第s堆到第t堆的石头总数是多少
Input
多组测试数据,第一行为数据组数T(0<T<15)
对于每组测试数据,第一行输入两个整数n和m(1<= n,m <= 100000),n,m意义如上描述
接下来一行n个整数,代表每堆石子数
接下来一行m行,每行两个数s,t分别代表一次询问
Output
对于每组数据,输出m行,表示每次询问的答案。
Sample Input
1 5 3 1 2 3 4 5 1 2 2 5 1 5
Sample Output
3 14 15
做法很多,巩固下树状数组。。
/****************************************************
* author:crazy_石头
* Pro:BUAA 815
* algorithm:树状数组
* Time:184ms
* Judge Status:Accepted
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
#define rep(i,h,n) for(int i=(h);i<=(n);i++)
#define ms(a,b) memset((a),(b),sizeof(a))
#define eps 1e-8
#define INF 1<<29
#define LL long long
const int maxn=100000+5;
LL C[maxn],n;
inline LL lowbit(LL x)
{
return x&(-x);
}
inline void update(LL x,LL num)
{
while(x<=maxn)
{
C[x]+=num;
x+=lowbit(x);
}
}
inline LL getsum(LL x)
{
LL res=0;
while(x>0)
{
res+=C[x];
x-=lowbit(x);
}
return res;
}
LL a[maxn];
int main()
{
int test;
LL ret;
scanf("%d",&test);
while(test--)
{
int n,m;
scanf("%d%d",&n,&m);
ms(C,0);
rep(i,1,n)
{
scanf("%lld",&a[i]);
update(i,a[i]);
}
while(m--)
{
LL l,r;
scanf("%lld%lld",&l,&r);
ret=getsum(r)-getsum(l-1);
printf("%lld\n",ret);
}
}
return 0;
}