学可持久化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(主席树+标记永久化)的更多相关文章

  1. hdu4348区间更新的主席树+标记永久化

    http://acm.hdu.edu.cn/showproblem.php?pid=4348 sb的标记永久化即可,刚开始add和sum没复制过来wa了两发...,操作和原来的都一样,出来单点变成区间 ...

  2. SP11470 TTM - To the moon[主席树标记永久化]

    SP11470 TTM - To the moon C l r d:区间 \([L,R]\) 中的数都加 d ,同时当前的时间戳加 1. Q l r:查询当前时间戳区间 \([L,R]\) 中所有数的 ...

  3. Codeforces 258E - Little Elephant and Tree(根号暴力/线段树+标记永久化/主席树+标记永久化/普通线段树/可撤销线段树,hot tea)

    Codeforces 题目传送门 & 洛谷题目传送门 yyq:"hot tea 不常有,做过了就不能再错过了" 似乎这是半年前某场 hb 模拟赛的 T2?当时 ycx.ym ...

  4. [HNOI2015]开店(树剖+主席树+标记永久化)

    听说正解点分树?我不会就对了 此题是 \([LNOI2014]LCA\) 强化版,也是差分一下,转化为区间加区间和 不过权值有大小要求,那么我们按照权值排序,依次加入主席树,询问的时候 \(lower ...

  5. HDU 4348(主席树 标记永久化)

    题面一看就是裸的数据结构题,而且一看就知道是主席树... 一共四种操作:1:把区间[l, r]的数都加上d,并且更新时间.2:查询当前时间的区间和.3:查询历史时间的区间和.4:时光倒流到某个时间. ...

  6. hdu4348 To the moon (主席树 || 离线线段树)

    Problem Description Background To The Moon is a independent game released in November 2011, it is a ...

  7. BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】

    题目链接 BZOJ4785 题解 肝了一个下午QAQ没写过二维线段树还是很难受 首先题目中的树状数组实际维护的是后缀和,这一点凭分析或经验或手模观察可以得出 在\(\mod 2\)意义下,我们实际求出 ...

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

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

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

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

随机推荐

  1. libvirt工具实现虚拟机管理

    libvirt工具实现虚拟机管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.介绍virt-install命令的常用参数 virt-install是一个命令行工具,它能够为K ...

  2. 挂载报错:“/dev/vda1 is apparently in use by the system;”

    挂载报错:“/dev/vda1 is apparently in use by the system;” 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 距离回家倒计时还有一天,明天 ...

  3. jQuery1.11源码分析(3)-----Sizzle源码中的浏览器兼容性检测和处理[原创]

    上一章讲了正则表达式,这一章继续我们的前菜,浏览器兼容性处理. 先介绍一个简单的沙盒测试函数. /** * Support testing using an element * @param {Fun ...

  4. iOS 根据生日得到生肖,星座,年龄的算法

    根据用户生日,得到相应的年龄,星座和生肖.有的项目中可能会用到,贴出来共享. 得到年龄,这个很简单了: - (void)getAgeWith:(NSDate*)birthday{ //日历 NSCal ...

  5. nmap - 网络扫描

    NMap,Network Mapper 最早是Linux下的网络扫描和嗅探工具包 网络链接扫描; nmap -PT 192.168.1.1-111 # 先ping在扫描主机开放端口 nmap -O 1 ...

  6. c++刷题(30/100)

    题目一:合并两个排序的链表 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 思路:利用两个指针cur1,cur2来指分别向两个链表中当前较小的和当前较大的 ...

  7. linux的lemon安装示范

    \(First\): 1. 准备好 lemon原文件 2. 解压压缩包(名字必须是lemon) 第二步:找到readme.md这个文件 第三步:了解一下安装指南 第四步:打开终端 注意:源代码目录就是 ...

  8. 原生JS获取元素的位置与尺寸

    1.内高度.内宽度: 内边距 + 内容框 element.clientWidth element.clientHeight 2.外高度,外宽度: 边框 + 内边距 + 内容框 element.offs ...

  9. Python学习四|变量、对象、引用的介绍

    变量 变量创建:一个变量也就是变量名,就像a,当代码第一次赋值时就创建了它.之后的赋值将会改变已创建的变量名的值,从技术上讲,Python在代码运行之前先检测变量名,可以当成是最初的赋值创建了变量. ...

  10. pyqt5-基础

    PyQt5是一套来自Digia的Qt5应用框架和Python的粘合剂.支持Python2.x和Python3.x版本. PyQt5以一套Python模块的形式来实现功能.它包含了超过620个类,600 ...