摘自知乎:最后一刹那,心电检测仪发出永恒的线声,耳机传来主题曲,画面定格在美丽的月球,情绪被扯进澎湃的漩涡中,眼睛开始模糊时,我才明白:……
\
\
To the moon
**Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 5573 Accepted Submission(s): 1265
**
\
Problem Description
Background
To The Moon is a independent game released in November 2011, it is a role-playing adventure game powered by RPG Maker.
The premise of To The Moon is based around a technology that allows us to permanently reconstruct the memory on dying man. In this problem, we'll give you a chance, to implement the logic behind the scene.
You‘ve been given N integers A [1], A [2],..., A [N]. On these integers, you need to implement the following operations:
1. C l r d: Adding a constant d for every {A i | l <= i <= r}, and increase the time stamp by 1, this is the only operation that will cause the time stamp increase.
2. Q l r: Querying the current sum of {A i | l <= i <= r}.
3. H l r t: Querying a history sum of {A i | l <= i <= r} in time t.
4. B t: Back to time t. And once you decide return to a past, you can never be access to a forward edition anymore.
.. N, M ≤ 10 5, |A [i]| ≤ 10 9, 1 ≤ l ≤ r ≤ N, |d| ≤ 10 4 .. the system start from time 0, and the first modification is in time 1, t ≥ 0, and won't introduce you to a future state.
\
Input
n m
A 1 A 2 ... A n
... (here following the m operations. )
\
Output
... (for each query, simply print the result. )
\
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
2 4
0 0
C 1 1 1
C 2 2 -1
Q 1 2
H 1 2 1
\
Sample Output
4
55
9
15
0
1
\
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
const int N = 1e5 + 7;
int T[N], tot, n, m;
int lson[N * 30], rson[N * 30], add[N * 30];
long long sum[N * 30];
inline void pushUp(int rt) {
sum[rt] = sum[lson[rt]] + sum[rson[rt]];
}
int build(int l, int r) {
int rt = tot++;
add[rt] = 0;
if (l == r) {
scanf("%lld", sum + rt);
return rt;
}
int mid = l + r >> 1;
lson[rt] = build(l, mid);
rson[rt] = build(mid + 1, r);
pushUp(rt);
return rt;
}
int update(int rt, int l, int r, int L, int R, int val) {
int k = tot++; //k是新的根节点
lson[k] = lson[rt]; rson[k] = rson[rt];
add[k] = add[rt]; sum[k] = sum[rt];
sum[k] += (long long)val * (R - L + 1);
if (l == L && r == R) {
add[k] += val; //修改延迟标记
return k;
}
int mid = l + r >> 1;
if (R <= mid) lson[k] = update(lson[k], l, mid, L, R, val);
else if (L > mid) rson[k] = update(rson[k], mid + 1, r, L, R, val);
else {
lson[k] = update(lson[k], l, mid, L, mid, val);
rson[k] = update(rson[k], mid + 1, r, mid + 1, R, val);
}
return k;
}
long long query(int rt, int l, int r, int L, int R) {
if (l == L && r == R) return sum[rt];
int mid = l + r >> 1;
long long res = (long long)add[rt] * (R - L + 1);
if (R <= mid)
return res + query(lson[rt], l, mid, L, R);
else if (L > mid)
return res + query(rson[rt], mid + 1, r, L, R);
else return res + query(lson[rt], l, mid, L, mid)
+ query(rson[rt], mid + 1, r, mid + 1, R); //注意这里
}
void init() {
tot = 0;
memset(sum, 0, sizeof sum);
memset(add, 0, sizeof add);
memset(T, 0, sizeof T);
}
int main()
{
while (~scanf("%d%d", &n, &m)) {
int x, y, val, now = 0;
char opt;
init();
T[0] = build(1, n);
while (m-- > 0) {
scanf(" %c", &opt);
switch(opt) {
case 'B':
scanf("%d", &now);
break;
case 'H':
scanf("%d%d%d", &x, &y, &val);
printf("%lld\n", query(T[val], 1, n, x, y));
break;
case 'Q':
scanf("%d%d", &x, &y);
printf("%lld\n", query(T[now], 1, n, x, y));
break;
case 'C':
scanf("%d%d%d", &x, &y, &val);
++now;
T[now] = update(T[now - 1], 1, n, x, y, val);
break;
}
}
}
return 0;
}
\
这道题我用普通的线段树离线操作没有解出来,可能不能用吧,时光穿梭到过去,会改变将来的
\
PS:这是国外自由鸟freebrid开发的,所以大家可能玩不成
\