A Simple Problem with Integers
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. 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.
Source
POJ Monthly--2007.11.25, Yang Yi
|
點擊打開題目鏈接
想要寫點什麼,又不知怎麼寫。(ps:剛剛入門)
(藍橋,省賽,天梯。。。一堆的比賽就要將自己的小身板壓垮了,堅持!想想兩個月後就要加入了程序猿的隊伍,期待又膽怯。
越努力,越幸運---致默默爲祖國IT事業做出自己貢獻的網絡搬運工)
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL;
#define Lson 2 * o, L, M //左兒子 宏定義 會有意想不到的好處
#define Rson 2 * o + 1, M + 1, R //右兒子
#define lo 2 * o
#define ro 2 * o + 1
const int maxn = 4 * 100000 + 10;
int ql, qr, v;
long long sum[maxn], add[maxn];
//向上傳遞,由 o 的左右子樹更新 o
void pushUp(int o)
{
sum[o] = sum[lo] + sum[ro];
}
//向下傳遞,維護節點o
void pushDown(int o, int m)
{
if (add[o]) //本節點有標記才傳遞
{
add[lo] += add[o]; //左子樹點增加
add[ro] += add[o]; //右子樹點增加
sum[lo] += add[o] * (m - (m / 2)); //左子樹區間段增加
sum[ro] += add[o] * (m / 2); //右子樹區間段增加
add[o] = 0; //清除本節點標記
}
}
//建樹
void Build(int o, int L, int R)
{
add[o] = 0; //建樹時初始節點都未標記
if (L == R) scanf("%lld", &sum[o]); //葉子節點
else
{
int M = (L + R) / 2;
Build(Lson); //建立左子樹
Build(Rson); //建立右子樹
pushUp(o); //更新本節點
}
}
//更新區間 [ql,qr] 內的值加上 v
void Update(int o, int L, int R)
{
if (ql <= L && qr >= R) //遞歸邊界
{
add[o] += v; //累加邊界的add值
sum[o] += v * (R - L + 1); //計算區間和
}
else
{
pushDown(o, R - L + 1);
int M = (L + R) / 2;
if (ql <= M) Update(Lson); //先遞歸更新左子樹或者右子樹
if (qr > M) Update(Rson);
pushUp(o); //更新本節點
}
}
//查詢區間[ql,qr] 的和
LL Query(int o, int L, int R)
{
if (ql <= L && qr >= R) //遞歸邊界
{
return sum[o];
}
else
{
pushDown(o, R - L + 1); //用邊界區間的附加信息更新答案
int M = (L + R) / 2;
LL ans = 0; //遞歸統計,累加參數add
if (ql <= M) ans += Query(Lson);
if (qr > M) ans += Query(Rson);
return ans;
}
}
int main()
{
int n, q;
while (~scanf("%d%d", &n, &q))
{
Build(1, 1, n);
char ch[5];
for (int i = 1; i <= q; i++)
{
scanf("%s", ch);
if (ch[0] == 'Q')
{
scanf("%d%d", &ql, &qr);
printf("%lld\n", Query(1, 1, n));
}
else
{
scanf("%d%d%d", &ql, &qr, &v);
Update(1, 1, n);
}
}
}
return 0;
}