E - Kuriyama Mirai's Stones CodeForces - 433B(解题报告)

Kuriyama Mirai has killed many monsters and got many (namely n) stones. She numbers the stones from 1 to n. The cost of the i-th stone is vi. Kuriyama Mirai wants to know something about these stones so she will ask you two kinds of questions:

  1. She will tell you two numbers, l and r (1 ≤ l ≤ r ≤ n), and you should tell her .
  2. Let ui be the cost of the i-th cheapest stone (the cost that will be on the i-th place if we arrange all the stone costs in non-decreasing order). This time she will tell you two numbers, l and r (1 ≤ l ≤ r ≤ n), and you should tell her .

For every question you should give the correct answer, or Kuriyama Mirai will say "fuyukai desu" and then become unhappy.

Input

The first line contains an integer n (1 ≤ n ≤ 105). The second line contains n integers: v1, v2, ..., vn (1 ≤ vi ≤ 109) — costs of the stones.

The third line contains an integer m (1 ≤ m ≤ 105) — the number of Kuriyama Mirai's questions. Then follow m lines, each line contains three integers type, l and r (1 ≤ l ≤ r ≤ n; 1 ≤ type ≤ 2), describing a question. If type equal to 1, then you should output the answer for the first question, else you should output the answer for the second one.

Output

Print m lines. Each line must contain an integer — the answer to Kuriyama Mirai's question. Print the answers to the questions in the order of input.

Example
Input
6
6 4 2 7 2 7
3
2 3 6
1 3 4
1 1 6
Output
24
9
28
Input
4
5 5 2 3
10
1 2 4
2 1 4
1 1 1
2 1 4
2 1 2
1 1 1
1 3 3
1 1 3
1 4 4
1 2 2
Output
10
15
5
15
5
5
2
12
3
5

这道题初看感觉很简单,不就循环就解决了吗。当很高兴的这样做了之后,你会很高兴的发现TLE了,哈哈哈。就是这样,这并不是简单的循环就可以解决的,我们需要用到动态规划。

这道题可以把数组的每个元素存储为前n个值的和,因为有两种方式求值,第二种方式就先排序后,再存储每个数,前几个数的和。最后答案也就可以输出为第r个数的前面值的和减去第l-1个数的

就可以得到值。

#include <stdio.h>
#include <algorithm>
using namespace std;
__int64 stone1[100005],stone2[100005],ans[100005];//题目中有说明值的范围可能会很大,所以不用int而是用__int64
int main()
{
	int i,n,m,type,l,r;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%I64d",&stone1[i]);
		stone2[i] = stone1[i];
		if(i)
		{
			stone1[i] += stone1[i-1];
		}
	}//第一个问题的初始化以及相关的处理,以及先为第二个需要的数组进行赋值。
	/*for(i=0;i<n;i++)
	{
		printf("%d ",stone1[i]);
	}
	printf("\n");*/
	scanf("%d",&m);
	sort(stone2,stone2+n);
	for(i=1;i<n;i++)
	{
		stone2[i] += stone2[i-1];
	}
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d",&type,&l,&r);
		if(type==1)
		{
			if(l==1)
			{
				ans[i] = stone1[r-1];
			}
			else
			{
				ans[i] = stone1[r-1] - stone1[l-2];//推断一下,需要的值和处理的在数组中的位置,就可以得出这种关系。
			}
		}
		else
		{
			if(l==1)
			{
				ans[i] = stone2[r-1];
			}
			else
			{
				ans[i] = stone2[r-1] - stone2[l-2];
			}
		}
	}
	for(i=0;i<m;i++)
	{
		printf("%I64d\n",ans[i]);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值