[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 ...
随机推荐
- DataGridView更新数据到数据库
WinFrom程序绑定了一个DataGridView控件,我需要添加一个button按钮来更改状态,还需要把更新之后的状态更新到数据库,如下图所示的这样: 首先先来拖控件,把界面做出来,自己拖一个Da ...
- IIS发布MVC出错
一个MVC网站在发布到IIS上时,出现了这个问题: 然后解决办法: 然后应用程序池那里,自己点右键添加一个 新建完应用池之后选中点高级设置 最后,添加网站,添加网站的时候应用程序池选择自己刚刚新建的那 ...
- .net 里面打不出来ConfigurationManager
ConfigurationManager 这个东东是读取配置文件时需要的. 首先要引用命名空间里面 using System.Configuration; 其次呢,在解决方案的引用里,单机右键进行添加
- Hadoop Yarn源码 - day2
接着昨天的继续看hadoop-yarn-api,昨天看了api package下的4个协议,今天来看下con package下的代码 conf目录下的内容比较少,就4个文件分别是Configurati ...
- bzoj千题计划258:bzoj3123: [Sdoi2013]森林
http://www.lydsy.com/JudgeOnline/problem.php?id=3123 启发式合并主席树 #include<cmath> #include<cstd ...
- dp的进阶 (一)
熟练掌握dp的定义方法. ①四维dp的转移,生命值转移时候需要注意的 ②集合的定义,判断二进制内部是否有环 ③很难想到的背包问题 ④博弈类型的dp ⑤排列组合类型dp ⑥01背包的变种(01背包+完全 ...
- 自定义泛型_无多态_通配符无泛型数组_jdk7泛型使用
通配符 T, K, V, E 等泛型字母为有类型, 类型参数赋予具体的值 ? 未知类型 类型参数赋予不确定值, 任意类型 只能用在 声明类型上,方法参数上, 不能用在定义泛型类上 上限 extends ...
- css 基础2
1.内部样式表: 2.行内样式表:在标签内写style,适合style 比较少的情况 3.外部样式表(外联式): 4.html标签可以分为:块级标签,h1~h6,div ,p,ul,ol,li,div ...
- GraphChi/graphchi-java程序配置
1.导入graphchi-java maven项目时报错: Plugin execution not covered by lifecycle configuration: org.scala-too ...
- [游戏数据分析]WAU模型简介及WAU预测
声明:本博客中所采用的数据并非真实数据,会对真实数据加以变换,重在讨论游戏数据分析的思路. 这里是参考友盟的WAU模型[文章网址, 演示网址],利用某款游戏(以下称为游戏A)数据进行的分析. 作用: ...