區間和 (蘇州大學計算機學院三月月賽暨藍橋杯熱身賽)


BannerHome 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

15
12
2

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




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com