3189. 求和

单点时限: 3.0 sec

内存限制: 256 MB

有一个数组,由n(1≤n≤1000)个值小于等于100的正整数元素组成。用该数组的每个非空子数组(显然共有n*(n+1)/2个子数组)的元素之和建立一个新的数组。对新数组按递增次序排序。

例如:数组[2, 3, 2]的子数组有6个:[2], [3], [2], [2, 3], [3, 2], [2, 3, 2]。排序后新数组为[2, 2, 3, 5, 5, 7]。

注意:子数组指连续的元素组成的数组。

现在给定L,U表示新数组的下标(这里假设数组的下标从1开始计),1≤L≤U≤n∗(n+1)/2,计算出下标L到U的元素的和。

L,U共有m(1≤m≤20)组。

例如: 前面例子中L=1,U=2时的和为4,L=2,U=4时的和为10。

输入格式
第 1 行:整数 T (1≤T≤10) 为问题数。

第2 m+3行:第一个问题的数据。一行由一个空格分隔的两个整数,表示n和m。下一行是原数组的n个由一个空格分隔的元素。后面是m行L和U, L和U之间有一个空格。

第m+3 T∗(m+2)+1行:后面问题的数据,格式与第一个问题相同。

输出格式
对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等),然后是m行,在每一行中输出按要求计算出的和。

样例
input
3
1 1
1
1 1
3 2
2 3 2
1 2
2 4
5 5
5 4 3 2 1
1 1
1 10
1 15
3 8
4 11
output
case #0:
1
case #1:
4
10
case #2:
1
45
105
26
48

/*
思路:后面的每个数为他前面一轮的从第一个位置的数加第k轮时从原数组的k位置之和。
*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int t;
	cin>>t;
	for(int i = 0; i < t; i++) {
		int n,m;
		cin>>n>>m;
		vector<int>v;
		for(int j = 0; j < n; j++) {
			int d;
			cin>>d;
			v.push_back(d);
		}
		vector<int>v2;
		v2=v;
		int index2=1;
		n--;
		while(n) {
			int k=n;
			int w=index2;
			int index1=v.size()-k-1;
			for(int j = 0; j < k; j++) {
				int l=v[index1++]+v2[w++];
				v.push_back(l);
			}
			index2++;
			n--;
		}
		sort(v.begin(),v.end());
		printf("case #%d:\n",i);
		for(int j = 0; j < m; j++) {
			int l,u;
			cin>>l>>u;
			int ans=0;

			for(int z=l-1; z<=u-1; z++) {
				ans+=v[z];
			}
			cout<<ans<<endl;
		}
	}
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值