poj 3468 A Simple Problem with Integers

来源:互联网 发布:excel怎么复制整列数据 编辑:程序博客网 时间:2024/05/08 00:36

splay区间求和,给区间加上某个数

//#include <bits/stdc++.h>#include <algorithm>#include <cstdio>#include <iostream>#include <cstring>#include <cmath>using namespace std;#define LL long long #define inf 0x3f3f3f3f#define MP make_pair#define pii pair<int, int>#define md (ll + rr >> 1)#define N 100010#define M 200020int pre[N], ch[N][2], sz[N];int tot, root, rt[N], a[N];LL sum[N], add[N], key[N];int creat(int p, int val){int k = ++tot;pre[k] = p;ch[k][0] = ch[k][1] = 0;sum[k] = key[k] = val;add[k] = 0;sz[k] = 1;return k;}void push_up(int k){sum[k] = sum[ch[k][0]] + sum[ch[k][1]] + key[k];sz[k] = sz[ch[k][0]] + sz[ch[k][1]] + 1;}void _add(int k, LL val){if(!k) return ;key[k] += val;sum[k] += val * sz[k];add[k] += val;}void push_down(int k){if(!k) return ;if(add[k]){_add(ch[k][0], add[k]);_add(ch[k][1], add[k]);add[k] = 0;}}void rot(int x){int y = pre[x], d = ch[y][1] == x;ch[y][d] = ch[x][!d];if(ch[x][!d]) pre[ch[x][!d]] = y;ch[x][!d] = y;pre[x] = pre[y];pre[y] = x;if(pre[x]) ch[pre[x]][ch[pre[x]][1] == y] = x;push_up(y);}void P(int x){if(!x) return;P(pre[x]);push_down(x);}void splay(int x, int goal){P(x);while(pre[x] != goal){int f = pre[x], ff = pre[f];if(ff == goal)rot(x);else if((ch[ff][1] == f) == (ch[f][1] == x))rot(f), rot(x);else rot(x), rot(x);}push_up(x);if(goal == 0) root = x;}int build(int ll, int rr, int p){if(ll > rr) return 0;int x = creat(p, a[md]);rt[md] = x;ch[x][0] = build(ll, md - 1, x);ch[x][1] = build(md + 1, rr, x);push_up(x);return x;}int main(){int n, m;while(scanf("%d%d", &n, &m) != EOF){tot = 0;for(int i = 1; i <= n; ++i)scanf("%d", &a[i]);a[0] = a[n + 1] = 0;root = build(0, n + 1, 0);while(m--){char s[5];int l, r, c;scanf("%s%d%d", s, &l, &r);if(s[0] == 'Q'){splay(rt[l-1], 0);splay(rt[r+1], root);int x = ch[ch[root][1]][0];printf("%lld\n", sum[x]);}else{scanf("%d", &c);splay(rt[l-1], 0);splay(rt[r+1], root);int x = ch[ch[root][1]][0];_add(x, c);}}}return 0;}


0 0