kyeremal-poj3468-A simple Problem with Integers-伸展树

来源:互联网 发布:combox控件绑定数据库 编辑:程序博客网 时间:2024/05/17 01:37

poj3468-A Simple Problem with Integers

A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 72128 Accepted: 22254Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , 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 A1A2, ... , 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 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

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

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 null 0#define LL long long#define INF 1152921504606846976#define MAXN 500010struct tree {    tree *p, *ch[2];    LL sum, c, add, siz;}*root, empty, fuck[MAXN];LL n, T_T, num[MAXN], cnt = 0;inline tree *kth(LL k) {    tree *f = root;    if (k < 1 || k > root->siz) return NULL;    for (; ; ) {LL lc = f->ch[0] != null ? f->ch[0]->siz : 0;LL rc = f->ch[1] != null ? f->ch[1]->siz : 0;if (k == lc+1) return f;if (k <= lc) f = f->ch[0];else f = f->ch[1], k -= lc + 1;    }}inline void update(tree *x) {    x->siz = x->ch[0]->siz + x->ch[1]->siz + 1;    x->sum = x->ch[0]->sum + x->ch[1]->sum + x->c;}inline void pushdown(tree *x) {    if (!x->add) return;    if (x->ch[0]) {x->ch[0]->add += x->add;x->ch[0]->sum += x->ch[0]->siz * x->add;x->ch[0]->c += x->add;    }    if (x->ch[1]) {x->ch[1]->add += x->add;x->ch[1]->sum += x->ch[1]->siz * x->add;x->ch[1]->c += x->add;    }    x->add = 0;}inline void rotate(tree *x, LL t) {    tree *y = x->p;    pushdown(y);    pushdown(x);    y->ch[t] = x->ch[!t];    y->ch[t]->p = y;    x->p = y->p;    if (y == y->p->ch[0]) y->p->ch[0] = x;    else y->p->ch[1] = x;    y->p = x;    x->ch[!t] = y;    update(y);    update(x);    if (y == root) root = x;}inline void splay(tree *x, tree *y) {    pushdown(x);    while (x->p != y) {if (x->p->p == y)    if (x == x->p->ch[0]) rotate(x, 0);    else rotate(x, 1);else    if (x->p == x->p->p->ch[0])if (x == x->p->ch[0]) rotate(x->p, 0), rotate(x, 0);else rotate(x, 1), rotate(x, 0);    elseif (x == x->p->ch[1]) rotate(x->p, 1), rotate(x, 1);else rotate(x, 0), rotate(x, 1);    }    update(x);    if (y == root->p) root = x;}inline tree *insert(LL *f, LL L, LL R) {    tree *r = fuck + ++cnt;    LL mid = (L + R) >> 1;    r->sum = r->c = f[mid];    r->siz = 1;    if (L <= mid-1) {r->ch[0] = insert(f, L, mid-1);r->siz += r->ch[0]->siz;r->sum += r->ch[0]->sum;    }    else r->ch[0] = ∅    if (mid+1 <= R) {        r->ch[1] = insert(f, mid+1, R);r->siz += r->ch[1]->siz;r->sum += r->ch[1]->sum;    }    else r->ch[1] = ∅    r->ch[0]->p = r->ch[1]->p = r;    return r;}inline LL query_sum(LL L, LL R) {    splay(kth(L-1), root->p);    splay(kth(R+1), root);    pushdown(root->ch[1]->ch[0]);    return root->ch[1]->ch[0]->sum;}inline void modify(LL L, LL R, LL cx) {    splay(kth(L-1), root->p);    splay(kth(R+1), root);    root->ch[1]->ch[0]->c += cx;    root->ch[1]->ch[0]->add += cx;    root->ch[1]->ch[0]->sum += cx * root->ch[1]->ch[0]->siz;}int main() {    cin >> n >> T_T;    memset(num, 0, sizeof(num));    rep(i, 1, n) scanf("%lld", &num[i+1]);    root = insert(num, 1, n+2);    root->p = ∅    root->p->ch[0] = root->p->ch[1] = root;    while (T_T--) {char ch[MAXN];LL x, y, t;scanf("%s", ch);if (ch[0] == 'Q') scanf("%lld%lld", &x, &y), printf("%lld\n", query_sum(x+1, y+1));if (ch[0] == 'C') scanf("%lld%lld%lld", &x, &y, &t), modify(x+1, y+1, t);    }}


0 0
原创粉丝点击