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
|
[Submit] [Go Back] [Status] [Discuss]
题意:
n个整数m个操作。每次操作:
Q a b 询问[a, b]的和
C a b c [a, b] 所有值+ c
线段树做非常简单 这里我学习Splay 用来试一下
第一道Splay
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define P64I1(a) printf(oform1, (a))
#define REP(i, n) for(int (i)=0; (i)<n; (i)++)
#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)
#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)
#define keyTree (ch[ch[root][1]][0])
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
const double PI = (4.0*atan(1.0));
const int maxn = 100000 + 20;
int ch[maxn][2], val[maxn], pre[maxn], size[maxn], S[maxn];
int root, top1, top2;
LL sumv[maxn], addv[maxn];
// debug
void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("结点%2d : 左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],val[x]);
Treaval(ch[x][1]);
}
}
void debug() {
printf("root=%d\n",root);
Treaval(root);
}
void New(int & r, int fa, int v) {
if(top2) r = S[--top2];
else r = ++top1;
pre[r] = fa;
size[r] = 1;
ch[r][0] = ch[r][1] = 0;
sumv[r] = val[r] = v;
addv[r] = 0;
}
void push_up(int r) {
size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
sumv[r] = sumv[ch[r][0]] + sumv[ch[r][1]] + val[r];
}
void push_down(int r) {
if(addv[r]) {
int lson = ch[r][0], rson = ch[r][1];
addv[lson] += addv[r];
val[lson] += addv[r];
addv[rson] += addv[r];
val[rson] += addv[r];
sumv[lson] += addv[r] * size[lson];
sumv[rson] += addv[r] * size[rson];
addv[r] = 0;
}
}
void Rotate(int x, int d) {
int y = pre[x];
push_down(x);
push_down(y);
ch[y][!d] = ch[x][d];
pre[ch[x][d]] = y;
if(pre[y]) ch[pre[y]][ch[pre[y]][1] == y] = x;
pre[x] = pre[y];
ch[x][d] = y;
pre[y] = x;
push_up(y);
}
void Splay(int x, int goal) {
push_down(x);
while(pre[x] != goal) {
if(pre[pre[x]] == goal)
Rotate(x, ch[pre[x]][0] == x);
else {
int y = pre[x];
int d = ch[pre[y]][0] == y;
if(ch[y][d] == x) {
Rotate(x, !d);
Rotate(x, d);
} else {
Rotate(y, d);
Rotate(x, d);
}
}
}
push_up(x);
if(goal == 0) root = x;
}
void RotateTo(int k, int goal) {
int r = root;
push_down(r);
while(size[ch[r][0]] != k) {
if(k < size[ch[r][0]]) r = ch[r][0];
else {
k -= size[ch[r][0]] + 1;
r = ch[r][1];
}
push_down(r);
}
Splay(r, goal);
}
int que[maxn];
void erase(int x) {
int y = pre[x];
int head = 0, tail = 0;
for(que[tail++] = x; head < tail; head++) {
int r = que[head];
S[top2++] = r;
if(ch[r][0]) que[tail++] = ch[r][0];
if(ch[r][1]) que[tail++] = ch[r][1];
}
ch[y][ch[y][1] == x] = 0;
push_up(y);
}
int A[maxn];
void build(int & r, int L, int R, int fa) {
if(L > R) return ;
int M = (L + R) / 2;
New(r, fa, A[M]);
if(L < M) build(ch[r][0], L, M-1, r);
if(M < R) build(ch[r][1], M+1, R, r);
push_up(r);
}
void init(int n) {
root = top1 = top2 = 0;
ch[0][0] = ch[0][1] = size[0] = pre[0] = 0;
addv[0] = sumv[0] = 0;
New(root, 0, -1);
New(ch[root][1], root, -1);
size[root] = 2;
build(keyTree, 1, n, ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
int getPre(int r) {
int t = ch[r][0];
if(!t) return INF;
while(ch[t][1]) t = ch[t][1];
return val[t];
}
int getNext(int r) {
int t = ch[r][1];
if(!t) return INF;
while(ch[t][0]) t = ch[t][0];
return val[t];
}
LL query(int L, int R) {
RotateTo(L-1, 0);
RotateTo(R+1, root);
return sumv[keyTree];
}
void update(int L, int R, int v) {
RotateTo(L-1, 0);
RotateTo(R+1, root);
addv[keyTree] += v;
val[keyTree] += v;
sumv[keyTree] += (LL) v * size[keyTree];
}
char str[10];
int main() {
int n, m;
while(scanf("%d%d", &n, &m) != EOF) {
for(int i=1; i<=n; i++) scanf("%d", &A[i]);
init(n);
while(m--) {
int a, b, c;
scanf("%s%d%d", str, &a, &b);
if(str[0] == 'Q') {
LL ans = query(a, b);
P64I(ans);
} else {
scanf("%d", &c);
update(a, b, c);
}
}
}
return 0;
}