poj3468-A Simple Problem with Integers
| Time Limit: 5000MS | Memory Limit: 131072K | |
| Total Submissions: 72128 | Accepted: 22254 | |
| Case Time Limit: 2000MS | ||
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 a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" 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
Hint
Source
POJ Monthly--2007.11.25, Yang Yi
splay tree
code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define rep(i, l, r) for (LL i = l; i <= r; i++)
#define REP(i, l, r) for (LL i = l; i >= r; i--)
#define INF 1152921504606846976
#define LL long long
#define MAXN 500010
LL n, root, T_T;
struct splay{LL p, s, ch[2], sum, add, c, siz;} a[MAXN];
inline void update(LL x) {
a[x].sum = a[a[x].ch[0]].sum + a[a[x].ch[1]].sum + a[x].c;
a[x].siz = a[a[x].ch[0]].siz + a[a[x].ch[1]].siz + 1;
}
inline void pushdown(LL x) {
if (!a[x].add) return;
a[a[x].ch[0]].c += a[x].add;
a[a[x].ch[1]].c += a[x].add;
a[a[x].ch[0]].add += a[x].add;
a[a[x].ch[1]].add += a[x].add;
a[a[x].ch[0]].sum += a[x].add * a[a[x].ch[0]].siz;
a[a[x].ch[1]].sum += a[x].add * a[a[x].ch[1]].siz;
a[x].add = 0;
}
inline void rotate(LL x, LL o) {
LL y = a[x].p;
pushdown(y);
pushdown(x);
a[y].ch[o] = a[x].ch[!o];
a[a[y].ch[o]].p = y;
a[x].p = a[y].p;
if (a[a[y].p].ch[0] == y) a[a[y].p].ch[0] = x;
else a[a[y].p].ch[1] = x;
a[y].p = x;
a[x].ch[!o] = y;
update(y);
if (root == y) root = x;
}
inline void splay(LL x, LL y) {
pushdown(x);
while (a[x].p != y) {
if (a[a[x].p].p == y)
if (a[a[x].p].ch[0] == x) rotate(x, 0);
else rotate(x, 1);
else if (a[a[a[x].p].p].ch[0] == a[x].p)
if (a[a[x].p].ch[0] == x) rotate(a[x].p, 0), rotate(x, 0);
else rotate(x, 1), rotate(x, 0);
else
if (a[a[x].p].ch[1] == x) rotate(a[x].p, 1), rotate(x, 1);
else rotate(x, 0), rotate(x, 1);
}
update(x);
if (!y) root = x;
}
inline void insert(LL x, LL y) {
a[x].sum = a[x].c = y;
a[x].s = x;
splay(x-1, a[root].p);
a[root].ch[1] = x;
a[x].p = root;
a[x].siz = 1;
a[root].siz++;
}
inline LL query_sum(LL L, LL R) {
splay(L-1, a[root].p);
splay(R+1, root);
pushdown(a[a[root].ch[1]].ch[0]);
return a[a[a[root].ch[1]].ch[0]].sum;
}
inline void modify(LL L, LL R, LL cx) {
splay(L-1, a[root].p);
splay(R+1, root);
a[a[a[root].ch[1]].ch[0]].c += cx;
a[a[a[root].ch[1]].ch[0]].add += cx;
a[a[a[root].ch[1]].ch[0]].sum += cx * a[a[a[root].ch[1]].ch[0]].siz;
}
int main() {
cin >> n >> T_T;
root = 1;
a[1].c = a[1].sum = 0;
a[1].s = -INF;
rep(i, 1, n) {
LL temp;
cin >> temp;
insert(i+1, temp);
}
a[n+2].sum = a[n+2].c = 0;
a[n+2].s = INF;
splay(n+1, a[root].p);
a[root].ch[1] = n+2;
a[n+2].p = root;
while (T_T--) {
char ch[20];
LL tx, ty, tz;
scanf("%s", ch);
if (ch[0] == 'Q') scanf("%lld%lld", &tx, &ty), printf("%lld\n", query_sum(tx+1, ty+1));
if (ch[0] == 'C') scanf("%lld%lld%lld", &tx, &ty, &tz), modify(tx+1, ty+1, tz);
}
}
kyeremal-poj3468-A simple Problem with Integers-伸展树
原文:http://blog.csdn.net/kyeremal/article/details/45951811