[HDU4348]To the moon(主席树+标记永久化)
学可持久化treap的时候才发现自己竟然没写过需要标记下传的主席树,然而现在发现大部分操作都可以标记永久化,下传会增大占用空间。
这题一种写法是和普通的线段树一样标记下传,注意所有修改操作(包括put())都要新建点。于是MLE了。
#include<cstdio>
#include<algorithm>
#define lson v[x].ls,L,mid
#define rson v[x].rs,mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
char op;
int n,m,l,r,k,tim,nd,a[N],rt[N];
struct Tr{ int ls,rs; ll sm,tag; }v[N*]; void put(int &x,int L,int R,ll k){ if (x) v[++nd]=v[x],x=nd,v[nd].sm+=(R-L+)*k,v[nd].tag+=k; } void push(int x,int L,int R){ int mid=(L+R)>>; if (v[x].tag) put(lson,v[x].tag),put(rson,v[x].tag),v[x].tag=; } void build(int &x,int L,int R){
x=++nd;
if (L==R){ v[x]=(Tr){,,a[L],}; return; }
int mid=(L+R)>>;
build(lson); build(rson);
v[x].sm=v[v[x].ls].sm+v[v[x].rs].sm; v[x].tag=;
} void ins(int y,int &x,int L,int R,int l,int r,int k){
x=++nd; v[x]=v[y];
if (L==l && r==R){ v[x].sm+=1ll*(R-L+)*k; v[x].tag+=k; return; }
int mid=(L+R)>>; push(x,L,R);
if (r<=mid) ins(v[y].ls,lson,l,r,k);
else if (l>mid) ins(v[y].rs,rson,l,r,k);
else ins(v[y].ls,lson,l,mid,k),ins(v[y].rs,rson,mid+,r,k);
v[x].sm=v[v[x].ls].sm+v[v[x].rs].sm;
} ll que(int x,int L,int R,int l,int r){
if (L==l && r==R) return v[x].sm;
int mid=(L+R)>>; push(x,L,R);
if (r<=mid) return que(lson,l,r);
else if (l>mid) return que(rson,l,r);
else return que(lson,l,mid)+que(rson,mid+,r);
} int main(){
freopen("hdu4348.in","r",stdin);
freopen("hdu4348.out","w",stdout);
while (~scanf("%d%d",&n,&m)){
rep(i,,n) scanf("%d",&a[i]);
nd=tim=; build(rt[],,n);
rep(i,,m){
scanf(" %c",&op);
if (op=='C') scanf("%d%d%d",&l,&r,&k),tim++,ins(rt[tim-],rt[tim],,n,l,r,k);
if (op=='Q') scanf("%d%d",&l,&r),printf("%lld\n",que(rt[tim],,n,l,r));
if (op=='H') scanf("%d%d%d",&l,&r,&k),printf("%lld\n",que(rt[k],,n,l,r));
if (op=='B') scanf("%d",&k),tim=k;
}
puts("");
}
return ;
}
未永久化(MLE)
另一种写法就是标记永久化,若一个修改区间覆盖当前区间则将tag+=k,但并不下传。询问时将答案加上tag的贡献即可。
注意多组数据的清空问题。
#include<cstdio>
#include<algorithm>
#define lson v[x].ls,L,mid
#define rson v[x].rs,mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
char op;
int n,m,l,r,k,tim,nd,flag,a[N],rt[N];
struct Tr{ int ls,rs; ll sm,tag; }v[N*]; void build(int &x,int L,int R){
x=++nd;
if (L==R){ v[x]=(Tr){,,a[L],}; return; }
int mid=(L+R)>>;
build(lson); build(rson);
v[x].sm=v[v[x].ls].sm+v[v[x].rs].sm; v[x].tag=;
} void ins(int y,int &x,int L,int R,int l,int r,int k){
x=++nd; v[x]=v[y]; v[x].sm+=1ll*(r-l+)*k;
if (L==l && r==R){ v[x].tag+=k; return; }
int mid=(L+R)>>;
if (r<=mid) ins(v[y].ls,lson,l,r,k);
else if (l>mid) ins(v[y].rs,rson,l,r,k);
else ins(v[y].ls,lson,l,mid,k),ins(v[y].rs,rson,mid+,r,k);
} ll que(int x,int L,int R,int l,int r){
if (L==l && r==R) return v[x].sm;
int mid=(L+R)>>,res=v[x].tag*(r-l+);
if (r<=mid) return res+que(lson,l,r);
else if (l>mid) return res+que(rson,l,r);
else return res+que(lson,l,mid)+que(rson,mid+,r);
} int main(){
freopen("hdu4348.in","r",stdin);
freopen("hdu4348.out","w",stdout);
while (~scanf("%d%d",&n,&m)){
if (flag) puts(""); else flag=;
rep(i,,n) scanf("%d",&a[i]);
nd=tim=; build(rt[],,n);
rep(i,,m){
scanf(" %c",&op);
if (op=='C') scanf("%d%d%d",&l,&r,&k),tim++,ins(rt[tim-],rt[tim],,n,l,r,k);
if (op=='Q') scanf("%d%d",&l,&r),printf("%lld\n",que(rt[tim],,n,l,r));
if (op=='H') scanf("%d%d%d",&l,&r,&k),printf("%lld\n",que(rt[k],,n,l,r));
if (op=='B') scanf("%d",&tim);
}
}
return ;
}
[HDU4348]To the moon(主席树+标记永久化)的更多相关文章
- hdu4348区间更新的主席树+标记永久化
http://acm.hdu.edu.cn/showproblem.php?pid=4348 sb的标记永久化即可,刚开始add和sum没复制过来wa了两发...,操作和原来的都一样,出来单点变成区间 ...
- SP11470 TTM - To the moon[主席树标记永久化]
SP11470 TTM - To the moon C l r d:区间 \([L,R]\) 中的数都加 d ,同时当前的时间戳加 1. Q l r:查询当前时间戳区间 \([L,R]\) 中所有数的 ...
- Codeforces 258E - Little Elephant and Tree(根号暴力/线段树+标记永久化/主席树+标记永久化/普通线段树/可撤销线段树,hot tea)
Codeforces 题目传送门 & 洛谷题目传送门 yyq:"hot tea 不常有,做过了就不能再错过了" 似乎这是半年前某场 hb 模拟赛的 T2?当时 ycx.ym ...
- [HNOI2015]开店(树剖+主席树+标记永久化)
听说正解点分树?我不会就对了 此题是 \([LNOI2014]LCA\) 强化版,也是差分一下,转化为区间加区间和 不过权值有大小要求,那么我们按照权值排序,依次加入主席树,询问的时候 \(lower ...
- HDU 4348(主席树 标记永久化)
题面一看就是裸的数据结构题,而且一看就知道是主席树... 一共四种操作:1:把区间[l, r]的数都加上d,并且更新时间.2:查询当前时间的区间和.3:查询历史时间的区间和.4:时光倒流到某个时间. ...
- hdu4348 To the moon (主席树 || 离线线段树)
Problem Description Background To The Moon is a independent game released in November 2011, it is a ...
- BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】
题目链接 BZOJ4785 题解 肝了一个下午QAQ没写过二维线段树还是很难受 首先题目中的树状数组实际维护的是后缀和,这一点凭分析或经验或手模观察可以得出 在\(\mod 2\)意义下,我们实际求出 ...
- HDU 4348 To the moon 主席树 在线更新
http://acm.hdu.edu.cn/showproblem.php?pid=4348 以前做的主席树没有做过在线修改的题做一下(主席树这种东西正经用法难道不是在线修改吗),标记永久化比较方便. ...
- hdu 4348 To the moon (主席树区间更新)
传送门 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q l r:查询当前时间戳区间[l,r]中所有数的和 . (3)H ...
随机推荐
- Hadoop生态圈-Flume的组件之拦截器与选择器
Hadoop生态圈-Flume的组件之拦截器与选择器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客只是配置的是Flume主流的Interceptors,想要了解更详细 ...
- Java FileReader使用相对路径读取文件
Java FileReader使用相对路径读取文件 觉得有用的话,欢迎一起讨论相互学习~Follow Me 在进行编程时需要时常更换主机进行测试,如果使用绝对路径则需要经常更改,为此使用相对路径是一个 ...
- bzoj千题计划272:bzoj4557: [JLoi2016]侦察守卫
http://www.lydsy.com/JudgeOnline/problem.php?id=4557 假设当前到了x的子树,现在是合并 x的第k个子树 f[x][j] 表示x的前k-1个子树该覆盖 ...
- 让你的HTML5&CSS3网站在老IE中也能正常显示的3种方法
起初,IE其实也是一款非常有进取心的浏览器.但经过一段时间的蛰伏后,它已经成为了我们生活中的一道障碍.微软现在又重新开始向其它浏览器发起挑战,但事实情况是,新版的现代IE浏览器一直滞后于谷歌浏览器和火 ...
- iOS 提交应用过程出现的错误及#解决方案#images can't contain alpha channels or transparencies
本文永久地址为http://www.cnblogs.com/ChenYilong/p/3977542.html ,转载请注明出处. 当你试图通过<预览>"导出&qu ...
- shiro登录成功之后跳转原路径
通过 WebUtils.getSavedRequest(request) 来获取shiro保存在session登录之前的url 1:java Controller代码 @PostMapping(&qu ...
- 各种卷积类型Convolution
从最开始的卷积层,发展至今,卷积已不再是当初的卷积,而是一个研究方向.在反卷积这篇博客中,介绍了一些常见的卷积的关系,本篇博客就是要梳理这些有趣的卷积结构. 阅读本篇博客之前,建议将这篇博客结合在一起 ...
- 第8月第15天 app支持后台播放
1. AVAudioSession *audioSession = [AVAudioSession sharedInstance]; //默认情况下扬声器播放 [audioSession setCat ...
- 【ARTS】01_06_左耳听风-20181217~1223
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- OE中的bitbake使用
OpenEmbedded是一些脚本(shell和python脚本)和数据构成的自动构建系统. 脚本实现构建过程,包括下载(fetch).解包(unpack).打补丁(patch).config ...