题意:有一个由n个数组成的序列,有4中操作:

1.C l r d [l,r]这段区间都加上d

2.Q l r 询问[l,r]这段区间的和

3.H l r t 询问之前t时间[l,r]的区间和

4.B t 回到t时间,且下一秒的时间从t开始

按时间建立主席树,主席树上的每一棵线段树维护[1,n]这段序列的信息,这里成段更新的时候要注意,以往写线段树的时候,都是把lazy标记向下传,但是写主席树的时候每一次下传,那么新的节点数就会非常多,会爆内存,所以我们不把lazy操作下传,只是在询问的时候,最后累加的答案加上每一个父亲节点上的lazy值。

 #include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e5+;
ll a[maxn];
int root[maxn];
struct node
{
int ln,rn;
ll lazy,sum;
}tree[maxn*]; int cnt;
void build(int &x,int l,int r)
{
++cnt;x=cnt;
tree[x].lazy=;
if(l==r){
tree[x].sum=a[l];
return;
}
int mid=l+r>>;
build(tree[x].ln,l,mid);
build(tree[x].rn,mid+,r);
tree[x].sum=tree[tree[x].ln].sum+tree[tree[x].rn].sum;
}
void update(int &x,int y,int L,int R,int l,int r,int val)
{
tree[++cnt]=tree[y];
x=cnt;
if(L==l&&R==r){
tree[cnt].lazy+=val;
tree[cnt].sum+=(R-L+)*val;
return;
}
tree[x].sum+=(R-L+)*val;
int mid=l+r>>;
if(R<=mid) update(tree[x].ln,tree[y].ln,L,R,l,mid,val);
else if(L>mid) update(tree[x].rn,tree[y].rn,L,R,mid+,r,val);
else{
update(tree[x].ln,tree[y].ln,L,mid,l,mid,val);
update(tree[x].rn,tree[y].rn,mid+,R,mid+,r,val);
}
}
ll query(int root,int L,int R,int l,int r)
{
ll ans=;
if(l==L&&r==R) return tree[root].sum;
ans+=(ll)tree[root].lazy*(ll)(R-L+);
int mid=l+r>>;
if(R<=mid) ans+=query(tree[root].ln,L,R,l,mid);
else if(L>mid) ans+=query(tree[root].rn,L,R,mid+,r);
else{
ans+=query(tree[root].ln,L,mid,l,mid);
ans+=query(tree[root].rn,mid+,R,mid+,r);
}
return ans;
}
void init()
{
cnt=;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
int now=;
build(root[],,n);
char t1[];int t2,t3,t4;
while(m--){
scanf("%s",t1);
if(t1[]=='Q'){
//当前时间线;
scanf("%d%d",&t2,&t3);
ll ans=query(root[now],t2,t3,,n);
printf("%lld\n",ans);
}
else if(t1[]=='C'){
now++;
scanf("%d%d%d",&t2,&t3,&t4);
update(root[now],root[now-],t2,t3,,n,t4);
}
else if(t1[]=='H'){
//某个时间线;
scanf("%d%d%d",&t2,&t3,&t4);
ll ans=query(root[t4],t2,t3,,n);
printf("%lld\n",ans);
}
else{
//返回某个时间线;
scanf("%d",&t2);
now=t2;
}
}
}
return ;
}

主席树 hdu 4348的更多相关文章

  1. 主席树 hdu 4417

    求一个区间内小于等于limit的数: 主席树模板题. 求出每一个节点的sum: #include<cstdio> #include<algorithm> #include< ...

  2. dfs序 线段树 dfs序列 主席树

    并查集 #include<stdio.h> ]; void sset(int x) { ;i<=x;i++) stt[i]=i; } int ffind(int x) { if(x= ...

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

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=4348 题意: 4种操作: C l r c   区间[l,r]加c,时间+1 Q l r    询问当前时 ...

  4. hdu 4348 To the moon (主席树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4348 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q ...

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

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

  6. To the moon HDU - 4348 (主席树,区间修改)

    Background To The Moon is a independent game released in November 2011, it is a role-playing adventu ...

  7. HDU 4348 To the moon(主席树 区间更新)题解

    题意: 给一个数组A[1] ~ A[n],有4种操作: Q l r询问l r区间和 C l r v给l r区间每个数加v H l r t询问第t步操作的时候l r区间和 B t返回到第t步操作 思路: ...

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

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

  9. HDU 4348 To the moon(主席树区间修改)

    题意 给你一个区间,支持如下操作: 在一段区间内加上一个值,并生成一个历史版本 查询某个版本下一段区间内的和 回到一个历史版本上并舍弃之后的版本 做法 这就是主席树区间修改裸题啦QwQ 上一篇博客我讲 ...

随机推荐

  1. Leetcode Week1 Regular Expression Matching

    Question Given an input string (s) and a pattern (p), implement regular expression matching with sup ...

  2. 《深入理解java虚拟机》读书笔记九——第十章

    第十章 早期(编译期)优化 1.Javac的源码与调试 编译期的分类: 前端编译期:把*.java文件转换为*.class文件的过程.例如sun的javac.eclipseJDT中的增量编译器. JI ...

  3. C#之Quartz任务调度的使用(2.2.3.400)

    这里使用的Quartz版本号为2.2.3.400,.net 框架为4.0. 目的实现一个小案例,每隔一秒钟打印一条记录.后面会附上源码,以供参考. 建立一个  控制台程序. 代码: class Pro ...

  4. SQL四种语言:DDL,DML,DCL,TCL 的区别

    1.DDL(Data Definition Language)数据库定义语言statements are used to define the database structure or schema ...

  5. git本地仓库远程仓库地址更改

    git remote rm origingit remote add origin git@52.82.8.87:iot3.0-service/test.gitgit push -u origin - ...

  6. rm -rf

    inux反选删除文件 最简单的方法是 # shopt -s extglob      (打开extglob模式) # rm -fr !(file1)  如果是多个要排除的,可以这样: # rm -rf ...

  7. HDU 1542 Atlantis(扫描线算法)

    题意:给出n个矩形的左下角左边和右上角坐标,求这n个矩形的面积并 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 典型的扫描线算法的题目 什么是 ...

  8. SQL Server查询中特殊字符的处理方法 (SQL Server特殊符号的转义处理)

    SQL Server查询中特殊字符的处理方法 (SQL Server特殊符号的转义处理) SQL Server查询中,经常会遇到一些特殊字符,比如单引号'等,这些字符的处理方法,是SQL Server ...

  9. 在sql server中如何检测一个字符串中是否包含另一个字符串

    select CHARINDEX('456','123456')   SQL语句使用CHARINDEX函数,来测试一个字符串中是否包含另一个字符串中的方法: 一.CHARINDEX函数介绍 1.函数功 ...

  10. mongodb多字段去重

    单字段去重 db.student.distinct("name"); 多字段去重 db.student.aggregate([{      $group:{            ...