Home PageDIY ContestsProblemsRanklistStatusStatistics
区间和
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 59 Accepted Submission(s) : 24
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
给出一个含有n个整数的数列a,并且有m次询问,每次询问数列在区间[l,r]内的和,即求a[l]+a[l+1]+……+a[r]的值。
Input
第一行为一个整数 T (1 ≤ T ≤ 50),表示共有T组输入数据;
对于每组数据,第一行是两个正整数 n,m (1 ≤ n ≤ 100000,1 ≤ m≤ 1000)分别代表数列长度和询问次数;
第二行行有 n 个正整数,第 i 个数表示数列元素 a[i] (1 ≤ a[i] ≤ 10^9)的值;
接下来 m 行,每行有两个正整数 l,r (1 ≤ l ≤ r ≤ n),代表询问内容。
Output
每组数据输出 m 行,每行一个数为该次询问的区间和。
保证数据都在64位正整数范围内。
Sample Input
2
5 2
1 2 3 4 5
1 5
3 5
4 1
1 1 1 1
1 2
Sample Output
Author
奚政
Statistic | Submit | Back
一道简单的线段树问题
做好了建树 ,然后搜索就行了
第一次没想数的范围wa了 改成longlong ac
#include <stdio.h>
#include <string.h>
struct node
{
long long a;
int l,r;
}tree[100000*4];
void build_tree(int left,int right,int root)
{
tree[root].l=left;
tree[root].r=right;
if(left==right)
{
scanf("%lld",&tree[root].a);
return ;
}
else
{
int mid=(left+right)/2;
build_tree(left,mid,root*2);
build_tree(mid+1,right,root*2+1);
tree[root].a=tree[root*2].a+tree[root*2+1].a;
}
}
void search_tree(int left,int right,int root,long long &sum)
{
if(left==tree[root].l&&right==tree[root].r)
{
sum=tree[root].a;
return ;
}
int mid=(tree[root].l+tree[root].r)/2;
if(left>mid)
search_tree(left,right,root*2+1,sum);
else if(right<=mid)
search_tree(left,right,root*2,sum);
else
{
long long sum1=0;
search_tree(left,mid,root*2,sum);
search_tree(mid+1,right,root*2+1,sum1);
sum=sum1+sum;
}
}
int main()
{
int ncase,n,m;
scanf("%d",&ncase);
while(ncase--)
{
memset(&tree,0,sizeof(&tree));
scanf("%d %d",&n,&m);
build_tree(1,n,1);
for(int i=0;i<m;i++)
{
int l1,r1;
long long sum=0;
scanf("%d %d",&l1,&r1);
search_tree(l1,r1,1,sum);
printf("%lld\n",sum);
}
}
return 0;
}