您的位置:首页 > 其它

[树状数组] poj3468 A Simple Problem with Integers

2015-07-23 10:36 330 查看
E - A Simple Problem with Integers

Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u

Submit

Status

Description

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 abc” means adding c to each of Aa, Aa+1, … , Ab. -10000 ≤ c ≤ 10000.

“Q ab” means querying the sum of Aa, Aa+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

使用改段求段的模型,就是上一篇树状数组里面总结的第三种模型,时空复杂度都比用线段树的做更小~

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int MAXN = 100020;
long long a[MAXN];
long long B[MAXN];
long long C[MAXN];
int n,Q;
//改段求段型:
//【1】修改操作:将A[l..r]之间的全部元素值加上c;
//ADD_B(r, c); ADD_C(r, c);
//if (l > 1) {ADD_B(l - 1, -c); ADD_C(l - 1, -c);}
//【2】求和操作:求此时A[l..r]的和。
//SUM(r) - SUM(l - 1)。

void ADD_B(int x, int c)
{
for (int i=x; i>0; i-=i&(-i))
B[i] += c;
}
void ADD_C(int x, int c)
{
for (int i=x; i<=n; i+=i&(-i))
C[i] += x * c;
}
long long SUM_B(int x)
{
int s = 0;
for (int i=x; i<=n; i+=i&(-i))
s += B[i];
return s;
}
long long SUM_C(int x)
{
int s = 0;
for (int i=x; i>0; i-=i&(-i))
s += C[i];
return s;
}
inline long long SUM(int x)
{
if (x)
return SUM_B(x) * x + SUM_C(x - 1);
else
return 0;
}

int main()
{
while(scanf("%d%d",&n,&Q) != EOF)
{
memset(a,0,sizeof(a));
memset(B,0,sizeof(B));
memset(C,0,sizeof(C));
for(int i =1; i<=n;i++)
scanf("%I64d",&a[i]);
for(int i =1; i<=n;i++)
{
ADD_B(i,a[i]);ADD_C(i,a[i]);
if(i > 1){ADD_B(i-1,-a[i]); ADD_C(i-1,-a[i]);}
}
char ch[20];
int num1,num2,num3;
while(Q--)
{
scanf("%s",ch);
if(ch[0] == 'Q')
{
scanf("%d%d",&num1,&num2);
printf("%I64d\n",SUM(num2)-SUM(num1-1));
}
else if (ch[0] =='C')
{
scanf("%d%d%d",&num1,&num2,&num3);
ADD_B(num2,num3); ADD_C(num2,num3);
if (num1>1)
{
ADD_B(num1-1,-num3); ADD_C(num1-1,-num3);
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: