HDU 4348(主席树 标记永久化)
题面一看就是裸的数据结构题,而且一看就知道是主席树。。。
一共四种操作:1:把区间[l, r]的数都加上d,并且更新时间。2:查询当前时间的区间和。3:查询历史时间的区间和。4:时光倒流到某个时间。
正常来说,主席树比较难支持区间操作,但是我们可以用标记永久化的方法去实现区间操作。标记永久化和懒标记下放不一样,标记永久化是这样操作的:对所有和标记区间相关的区间,直接加上这次操作的影响,如果这个区间被标记区间完全覆盖,就打上标记。查询的时候,需要把访问沿途的所有的区间的标记算上。
代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 100010;
struct SegementTree {
int ls, rs;
long long sum, flag;
};
SegementTree tr[maxn * 200];
int tot, a[maxn], root[maxn], Time;
void pushup(int now) {
tr[now].sum = tr[tr[now].ls].sum + tr[tr[now].rs].sum;
}
void build(int now, int l, int r) {
tr[now].ls = tr[now].rs = tr[now].sum = tr[now].flag = 0;
if(l == r) {
tr[now].sum = a[l];
tr[now].flag = 0;
return;
}
int mid = (l + r) >> 1;
tr[now].ls = ++tot; build(tot, l, mid);
tr[now].rs = ++tot; build(tot, mid + 1, r);
pushup(now);
}
void insert(int lnow, int rnow, int l, int r, int ql, int qr, LL val) {
tr[rnow] = tr[lnow];tr[rnow].sum += val * (qr - ql + 1);
if(l == ql && r == qr) {
tr[rnow].flag += val;
return;
}
int mid = (l + r) >> 1;
if(qr <= mid) {
tr[rnow].ls = ++tot; insert(tr[lnow].ls, tot, l, mid, ql, qr, val);
} else if(ql > mid) {
tr[rnow].rs = ++tot; insert(tr[lnow].rs, tot, mid + 1, r, ql, qr, val);
} else {
tr[rnow].ls = ++tot; insert(tr[lnow].ls, tot, l, mid, ql, mid, val);
tr[rnow].rs = ++tot; insert(tr[lnow].rs, tot, mid + 1, r, mid + 1, qr, val);
}
// pushup(rnow);
}
LL query(int now, int l, int r, int ql ,int qr) {
if(l >= ql && r <= qr) {
return tr[now].sum;
}
int mid = (l + r) >> 1;
LL ans = tr[now].flag * (qr - ql + 1);
if(qr <= mid) ans += query(tr[now].ls, l, mid, ql, qr);
else if(ql > mid) ans += query(tr[now].rs, mid + 1, r, ql, qr);
else {
ans += query(tr[now].ls, l, mid, ql, mid);
ans += query(tr[now].rs, mid + 1, r, mid + 1, qr);
}
return ans;
}
char s[10];
int main() {
int x, y, z, n, m, kase = 0;
while(~scanf("%d%d", &n, &m)) {
tot = 0, Time = 0;
kase++;
if(kase > 1) printf("\n");
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
root[0] = ++tot;
build(tot, 1, n);
while(m--) {
scanf("%s", s + 1);
if(s[1] == 'C') {
scanf("%d%d%d", &x, &y, &z);
root[++Time] = ++tot;
insert(root[Time - 1], root[Time], 1, n, x, y, z);
} else if(s[1] == 'Q') {
scanf("%d%d", &x, &y);
printf("%lld\n", query(root[Time], 1, n, x, y));
} else if(s[1] == 'H') {
scanf("%d%d%d", &x, &y, &z);
printf("%lld\n", query(root[z], 1, n, x, y));
} else {
scanf("%d", &x);
tot = root[x + 1] - 1;
Time = x;
}
}
}
}
HDU 4348(主席树 标记永久化)的更多相关文章
- Codeforces 258E - Little Elephant and Tree(根号暴力/线段树+标记永久化/主席树+标记永久化/普通线段树/可撤销线段树,hot tea)
Codeforces 题目传送门 & 洛谷题目传送门 yyq:"hot tea 不常有,做过了就不能再错过了" 似乎这是半年前某场 hb 模拟赛的 T2?当时 ycx.ym ...
- hdu4348区间更新的主席树+标记永久化
http://acm.hdu.edu.cn/showproblem.php?pid=4348 sb的标记永久化即可,刚开始add和sum没复制过来wa了两发...,操作和原来的都一样,出来单点变成区间 ...
- [HNOI2015]开店(树剖+主席树+标记永久化)
听说正解点分树?我不会就对了 此题是 \([LNOI2014]LCA\) 强化版,也是差分一下,转化为区间加区间和 不过权值有大小要求,那么我们按照权值排序,依次加入主席树,询问的时候 \(lower ...
- [HDU4348]To the moon(主席树+标记永久化)
学可持久化treap的时候才发现自己竟然没写过需要标记下传的主席树,然而现在发现大部分操作都可以标记永久化,下传会增大占用空间. 这题一种写法是和普通的线段树一样标记下传,注意所有修改操作(包括put ...
- HDU 4348 主席树区间更新
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- SP11470 TTM - To the moon[主席树标记永久化]
SP11470 TTM - To the moon C l r d:区间 \([L,R]\) 中的数都加 d ,同时当前的时间戳加 1. Q l r:查询当前时间戳区间 \([L,R]\) 中所有数的 ...
- hdu 5919 主席树(区间不同数的个数 + 区间第k大)
Sequence II Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 3954 线段树 (标记)
Level up Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
随机推荐
- 关于wm8740数据手册的严重错误
之前的一个项目使用了双wm8741的差动解码器,后来更换为双wm8740.由于8740不支持I2C通信,软控也就由I2C改为了SPI. 由于是双wm8740,需要一片负责左声道,一片负责右声道.因此要 ...
- 格式化SQL和逆格式SQL
上篇说过SQLyog中的计算合适数据类型的功能,现在说下Navicat格式化SQL和逆格式化SQL 啥也不说了,一看图,一目了然,Beautify SQL(格式化,即变成最美的语句)和Minify S ...
- uva1636 - Headshot(条件概率)
简单的条件概率题,直接再来一枪没子弹的概率是所有子串”00“的数目除以‘0’的数目,随机转一下再打没子弹的概率是‘0’的数目除以总数目. #include<iostream> #inclu ...
- len(),range()函数
len()函数返回字符串.列表.字典.元组等长度 eg1:计算字符串的长度: >>>s='hello good boy doiido' >>>len(s) > ...
- EF中使用Linq的Lambda比较字符串格式日期大小
在使用EF时,想要比较字符串类型的日期时,参考以下: SQL语句: 1)select * from TableName where StartTime > ‘2015-04-08‘ 2)sele ...
- c语言%.*s是什么
int i; ;i<;i++) printf("%.*s%s\n", i, " ", "########"); ; *用来指定宽度,对 ...
- 团队开发中Git冲突解决
正常来说我们团队协作开发过程中,冲突是常有的事,下面介绍下本人在开发中的解决办法. 冲突的主要原因就是由于我们开发人员在分支的同一位置写入了不一样的代码,然后合并到主干上导致我们冲突. 方法: 当冲突 ...
- 学习动态性能表(19)--v$undostat
学习动态性能表 第19篇--V$UNDOSTAT 2007.6.14 本视图监控当前实例中undo空间以及事务如何运行.并统计undo空间开销,事务开销以及实例可用的查询长度. V$UNDOSTAT ...
- 学习动态性能表(16)--v$rowcache
学习动态性能表 第16篇--V$ROWCACHE 2007.6.12 本视图显示数据字典缓存(也叫rowcache)的各项统计.每一条记录包含不同类型的数据字典缓存数据统计,注意数据字典缓存有层次差 ...
- linux 在vi文件中添加行号
方法一: 1.显示当前行行号,在VI的命令模式下输入 :nu 2.显示所有行号,在VI的命令模式下输入 :set nu 方法二: 使用vi编辑~/.vimrc文件,在该文件中加入一行"set ...