您的位置:首页 > 理论基础

区间和 (苏州大学计算机学院三月月赛暨蓝桥杯热身赛)

2016-03-10 20:13 309 查看



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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: