题意:

给出一个长度为\(n(n \leq 10^5)\)的序列,最开始时间\(t=0\),支持下面几个操作:

  • \(C \, l \, r \, d\):将区间\([l,r]\)每个数都加上\(d\),并且时间\(t\)增加1秒
  • \(Q \, l \, r\):查询当前时间区间\([l,r]\)所有元素之和
  • \(H \, l \, r \, t\):查询时间为\(t\)时,区间\([l,r]\)的所有元素之和
  • \(B \, t\):时间回溯到\(t\)

输出每次查询的结果。

分析:

这是支持区间修改的可持久化线段树。

我们维护一个\(sum\)表示区间的元素和以及一个懒惰标记\(add\)。

由于是主席树,查询时如果要\(pushdown\)就会新增节点,空间开销比较大。

所以查询时不进行\(pushdown\),而是累加所经过的节点的\(add\)值 乘上 查询区间长度。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long LL;
const int maxn = 100000 + 10; struct Node
{
int lch, rch, add;
LL sum;
}; int sz;
Node T[maxn << 5]; int n, m, root[maxn];
LL S[maxn];
char op[5]; int update(int pre, int L, int R, int qL, int qR, int v) {
int rt = ++sz;
T[rt] = T[pre];
T[rt].sum += (LL)v * (min(R, qR) - max(L, qL) + 1);
if(qL <= L && R <= qR) { T[rt].add += v; return rt; }
int M = (L + R) / 2;
if(qL <= M) T[rt].lch = update(T[pre].lch, L, M, qL, qR, v);
if(qR > M) T[rt].rch = update(T[pre].rch, M+1, R, qL, qR, v);
return rt;
} LL query(int rt, int L, int R, int qL, int qR) {
if(qL <= L && R <= qR) return T[rt].sum;
LL ans = (LL)T[rt].add * (min(R, qR) - max(L, qL) + 1);
int M = (L + R) / 2;
if(qL <= M) ans += query(T[rt].lch, L, M, qL, qR);
if(qR > M) ans += query(T[rt].rch, M+1, R, qL, qR);
return ans;
} int main()
{
bool flag = false;
while(scanf("%d%d", &n, &m) == 2) {
if(flag) puts(""); flag = true;
for(int i = 1; i <= n; i++) {
scanf("%lld", S + i);
S[i] += S[i - 1];
}
sz = 0; int time = 0;
while(m--) {
scanf("%s", op);
int l, r, d; scanf("%d", &l);
if(op[0] == 'C') {
scanf("%d%d", &r, &d);
time++;
root[time] = update(root[time - 1], 1, n, l, r, d);
} else if(op[0] == 'Q') {
scanf("%d", &r);
LL ans = S[r] - S[l - 1];
ans += query(root[time], 1, n, l, r);
printf("%lld\n", ans);
} else if(op[0] == 'H') {
scanf("%d%d", &r, &d);
LL ans = S[r] - S[l - 1];
ans += query(root[d], 1, n, l, r);
printf("%lld\n", ans);
} else {
time = l;
}
}
} return 0;
}

HDU 4348 To the moon 主席树的更多相关文章

  1. HDU 4348 To the moon 主席树 在线更新

    http://acm.hdu.edu.cn/showproblem.php?pid=4348 以前做的主席树没有做过在线修改的题做一下(主席树这种东西正经用法难道不是在线修改吗),标记永久化比较方便. ...

  2. hdu 4348 To the moon (主席树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4348 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q ...

  3. hdu 4348 To the moon (主席树区间更新)

    传送门 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q l r:查询当前时间戳区间[l,r]中所有数的和 . (3)H ...

  4. hdu 4348 To the moon 主席树区间更新

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Prob ...

  5. hdu 4348 To the moon (主席树 区间更新)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=4348 题意: 4种操作: C l r c   区间[l,r]加c,时间+1 Q l r    询问当前时 ...

  6. HDU 4348 To the moon(主席树 区间更新)题解

    题意: 给一个数组A[1] ~ A[n],有4种操作: Q l r询问l r区间和 C l r v给l r区间每个数加v H l r t询问第t步操作的时候l r区间和 B t返回到第t步操作 思路: ...

  7. HDU 4348 To the moon(主席树区间修改)

    题意 给你一个区间,支持如下操作: 在一段区间内加上一个值,并生成一个历史版本 查询某个版本下一段区间内的和 回到一个历史版本上并舍弃之后的版本 做法 这就是主席树区间修改裸题啦QwQ 上一篇博客我讲 ...

  8. HDU 4348 To the moon (主席树区间更新)

    题意:首先给你n个数,开始时间为0,最后按照操作输出 给你四种操作: 1. C l r d :  在(l,r)区间都加上d,时间加一2. Q l r :  询问现在(l,r)的区间和3. H l r ...

  9. HDU 4348.To the moon SPOJ - TTM To the moon -可持久化线段树(带修改在线区间更新(增减)、区间求和、查询历史版本、回退到历史版本、延时标记不下放(空间优化))

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

随机推荐

  1. 仙人掌(cactus)

    题目描述LYK 在冲刺清华集训(THUSC)!于是它开始研究仙人掌,它想来和你一起分享它最近研究的结果.如果在一个无向连通图中任意一条边至多属于一个简单环(简单环的定义为每个点至多经过一次),且不存 ...

  2. ORACLE行转列通用过程(转)

    1.使用视图 SQL code? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 create or r ...

  3. Unity的stateMachineBehaviour

    Unity5新增的StateMachineBehaviour是对状态机的内置,确实方便了很多,这里记录它的两个问题: 1.如果正在执行的状态被打断,当前状态的OnStateExit不会被执行,该问题在 ...

  4. RK3288开发过程中遇到的问题点和解决方法之Framework

    删除小电池图标及百分比 a.SystemUI/.../statusbar/policy/BatteryController.java mBatteryPercentageView.setVisibil ...

  5. jmeter参考网址

    http://blog.csdn.net/dongdong9223/article/details/49248979 http://blog.csdn.net/hjh00/article/detail ...

  6. MATLAB中容易忽略却经常遇到的小技巧总结

    1       如何产生一个列向量相同的矩阵 例如,列向量x=[1;2;3],要产生矩阵A=[x,x,x],即[1,1,1;2,2,2;3,3,3]. A = repmat(x,1,n) 2      ...

  7. POJ 1185 炮兵阵地 (状压DP,轮廓线DP)

    题意: 给一个n*m的矩阵,每个格子中有'P'或者'H',分别表示平地和高原,平地可以摆放大炮,而大炮的攻击范围在4个方向都是2格(除了自身位置),攻击范围内不能有其他炮,问最多能放多少个炮?(n&l ...

  8. 跑yscacaca/HHAR-Data-Process出现的问题

    直接按照说明跑: python dataAli-sameUserDevice.py python pairDataFile.py python sep_HHAR_data.py 但在sep_HHAR_ ...

  9. JSONPath - XPath for JSON

    http://goessner.net/articles/JsonPath/ [edit] [comment] [remove] |2007-02-21| e1 # JSONPath - XPath ...

  10. VS code 豆沙绿护眼主题

    一.下载亮色主题Atom One Light 二.找到settings.JSON,粘贴JSON 快捷键输入  Ctrl+Shift+p   ,输入settings,选择open settings (J ...