ZCMU 1687: 数组操作(前缀和)

Description

给你一个初始的长度为n的数组。(1<=n<=105)

有两个操作:

Op1(l, r):给两个整数l和r(1<=l<=r<=当前数组长度)。你需要计算数组从l到r的所有元素的和。

Op2(x):给你一个整数x(|x| <= 109),你需要将x添加到数组的头部。原先的第一个元素变成第二个元素,第二个元素变成第三个,以此类推。并且数组的长度增加1.

Input

多组测试数据,处理到文件结尾。

每组测试数据,首先给出一个N(1 <= N <= 105), 表示初始的数组的元素个数。

第二行N个数字表示初始数组的n个元素,a1 a2 ... aN.(|ai| <= 109)。

第三行有一个Q,表示有Q个操作。1 <= Q <= 105

接下来Q行,每行的第一个数表示操作的类型,只可能是1或者2,形式如下:

1 l r:操作1,求l到r的元素的和。

2 x:操作2,将x添加到数组头部。

Output

对于每组测试数据,首先输出"Case x:",表示当前是第x组测试数据。

然后对于每个操作1输出对应的答案,对于操作2不需要任何输出。

Sample Input

10 1 2 3 4 5 6 7 8 9 10 4 1 1 10 1 1 1 1 10 10 1 2 7 5 6 7 8 9 10 9 2 5 2 4 1 2 7 2 3 2 2 2 1 1 1 10 1 1 1 1 10 10

Sample Output

Case 1: 55 1 10 27 Case 2: 45 55 1 10
将数倒着存,所以往开头加数就变成了直接往末尾加一个数,然后改写为前缀和数组。
记得数组要开long long以及数组初始化........
#include
using namespace std;
typedef long long ll;
ll a[200010];
ll b[200010];
int main()
{
	int n;
	int cnt=0;
	while(~scanf("%d",&n))
	{
		memset(b,0,sizeof(b));
		memset(a,0,sizeof(a));
		cnt++;
		for(int i=1;i<=n;i++)
		{
			scanf("%lld",&a[i]);
		}
		for(int i=1;i<=n;i++)
		{
			b[i]=b[i-1]+a[n-i+1];
		}
		int q;
		scanf("%d",&q);
		printf("Case %d:\n",cnt);
		while(q--)
		{
			int k;
			scanf("%d",&k);
			if(k==1)
			{
				int l,r;
				scanf("%d %d",&l,&r);
				printf("%lld\n",b[n-l+1]-b[n-r]);
			}
			else if(k==2) 
			{
				int x;
				scanf("%d",&x);
				n++;
				b[n]=b[n-1]+x; 
			}
		}
	}
	return 0;
}

你可能感兴趣的:(算法,c++)