C - A Simple Problem with Integers (非递归版)

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

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

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;

const int MAXN = 100000 + 10;
long long sum[MAXN << 2], add[MAXN << 2], a[MAXN], N, n, m;

void build()
{
	while ( N < n + 2 )
		N <<= 1;
	for ( int i = 1; i <= n ; i ++ )
		sum[N + i] = a[i];
	for ( int i = N - 1; i > 0; i -- )
		sum[i] = sum[i << 1] + sum[i << 1 | 1];
}

long long query ( int L, int R )
{
	int s, t, x = 1, Ln = 0, Rn = 0;
	long long ans = 0;
	for ( s = N + L - 1, t = N + R + 1; s ^ t ^ 1; s >>= 1, t >>= 1, x <<= 1 )
	{
		if ( add[s] )
			ans += add[s] * Ln;
		if ( add[t] )
			ans += add[t] * Rn;
		if ( ~s & 1 )
			ans += sum[s ^ 1], Ln += x;
		if ( t & 1 )
			ans += sum[t ^ 1], Rn += x;
	}
	for ( ; s; s >>= 1, t >>= 1 )
	{
		ans += add[s] * Ln;
		ans += add[t] * Rn;
	}
	return ans;
}
void update ( int L, int R, int C )
{
	int s, t, Ln = 0, Rn = 0, x = 1;

	for ( s = L + N - 1, t = R + N + 1; s ^ t ^ 1; s >>= 1, t >>= 1, x <<= 1 )
	{
		sum[s] += C * Ln;
		sum[t] += C * Rn;
		if ( ~s & 1 )
			add[s ^ 1] += C, sum[s ^ 1] += C * x, Ln += x;
		if ( t & 1 )
			add[t ^ 1] += C, sum[t ^ 1] += C * x, Rn += x;
	}
	//cout << "!!!" << endl;
	for ( ; s; s >>= 1, t >>= 1 )
	{
		sum[s] += C * Ln;
		sum[t] += C * Rn;
	}
	//cout << "!!!" << endl;
}
int main()
{
	int x, y, k;
	char q[10];
	scanf ( "%d %d", &n, &m );
	N = 1;
	for ( int i = 1; i <= n; i ++ )
		scanf ( "%lld", &a[i] );
	build();
	while ( m -- )
	{
		scanf ( "%s %d %d", q, &x, &y );
		if ( q[0] == 'Q' )
			printf ( "%lld\n", query ( x, y ) );
		else if ( q[0] == 'C' )
		{
			scanf ( "%d", &k );
			//cout << x << " " << y << " " << k << endl;
			update ( x, y, k );
		}

	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ant_e_zz/article/details/81605844
今日推荐