学可持久化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. MySQL的备份和恢复-mysqldump

    MySQL的备份和恢复-mysqldump 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么需要备份 1>.做灾难恢复 天有不测风云嘛,如果你的服务器被黑客攻击了(比 ...

  2. bzoj千题计划273:bzoj4710: [Jsoi2011]分特产

    http://www.lydsy.com/JudgeOnline/problem.php?id=4710 答案=总方案数-不合法方案数 f[i][j] 前i种特产分给j个人(可能有人没有分到特产)的总 ...

  3. HttpClient与HttpUrlConnection下载速度比较

    Android有两套http的API,刚开始使用网络编程时多少有些迷惑到底用哪个好呢?其实孰优孰劣无需再争论,google已经指出HttpUrlConnection是Android更优的选择,并在SD ...

  4. shell ssh 批量执行

    ssh 批量执行命令 #版本1 #!/bin/bash while read line do Ip=`echo $line|awk '{print $1}'` Passwd=`echo $line|a ...

  5. 第13月第10天 swift3.0

    1. Type 'Any' has no subscript members 这一条简直莫名其妙.大体意思就是,你这个类型"Any"不是个数组或者字典,不能按照下标取东西. 我之前 ...

  6. bzoj3029 守卫者的挑战 (多维dp)

    题面: 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突然,眼前一道亮光闪过."我,Nizem,是黑魔法圣殿的守卫者.如果你能通过我的挑 ...

  7. 利用iis虚拟目录实现文件服务器功能

    要求说明: 通过网站上传文件保存到统一的文件服务器上. 服务器说明: 1.文件服务器以下称为FilesServer,IP地址为:192.168.1.213 2.Web服务器为以下称为WebServer ...

  8. lucene入门查询索引——(三)

    1.用户接口(lucene不提供)

  9. binlog2sql的安装及使用

    binlog2sql是大众点评开源的一款用于解析binlog的工具,在测试环境试用了下,还不错. DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法 ...

  10. casper Dom的操作

    phantom.casperTest = true; phantom.outputEncoding="utf-8"; var casper = require('casper'). ...