题意:首先给你n个数,开始时间为0,最后按照操作输出

给你四种操作:

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的时间

题解:首先是区间修改区间查询,可以想到线段树,接着就是询问历史版本与回到历史版本,这样就是主席树了

首先我们知道普通主席树是单点修改,并支持历史版本的区间求和与回到历史版本(就是这删除之后的树),仅仅只是因为它存了多棵线段树

而我们这儿是要进行区间修改,所以第一反应就是模拟线段树的lazy标记,并在查询时再更新再建树,但是这样会卡空间

因此我们需要这样想,模拟lazy标记进行重建树(最多建立2*log2(n)个节点)是必须的,但是查询时就不需要重建树了

这样我们就需要记录两个值:sum代表这一段中被增加区间的与此这一段的区间相交的总和,com代表这一段都需要增加这么多

这时我们查询时就需要每次加上com与待查询的区间相交的值(加上之前更新的),最后再包含的区间里加上sum再减去这儿com与待查询的区间相交的值(重复了)

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const ll INF=1ll<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=1e5+;
int root[Max],tot;
struct node
{
int lef,rig;
ll sum,com;//相交总共的和 这一段每个点都加上这个
}msegtr[Max*];
ll pre[Max];//把原来的数放入前缀和里,主席树里仅仅更新修改的值
void Init(int &cnt)
{
cnt=;
msegtr[].lef=msegtr[].rig=;
msegtr[].sum=msegtr[].com=0ll;
root[]=,tot=;
pre[]=0ll;
return;
}
int Jud(int sta,int enn,int lef,int rig)//关键的区间交
{
return max(min(rig,enn)-max(lef,sta)+,);
}
void Create(int sta,int enn,int &x,int y,int lef,int rig,int com)
{
msegtr[++tot]=msegtr[y];
msegtr[tot].sum+=(ll)com*Jud(sta,enn,lef,rig);
x=tot;
if(sta>=lef&&enn<=rig)//模拟线段树区间更新
{
msegtr[tot].com+=com;//这一段每个点都加上这个
return;
}
int mid=dir(sta+enn,);
if(mid>=lef)
Create(sta,mid,msegtr[x].lef,msegtr[y].lef,lef,rig,com);
if(mid<rig)
Create(mid+,enn,msegtr[x].rig,msegtr[y].rig,lef,rig,com);
return;
}
ll Query(int sta,int enn,int x,int lef,int rig)
{
if(sta>=lef&&enn<=rig)
{
return msegtr[x].sum-msegtr[x].com*Jud(sta,enn,lef,rig);//多加了,要减去
}
int mid=dir(sta+enn,);
ll ans=0ll;
if(mid>=lef)
{
ans+=Query(sta,mid,msegtr[x].lef,lef,rig)+msegtr[msegtr[x].lef].com*Jud(sta,mid,lef,rig);//加上区间交的值
}
if(mid<rig)
{
ans+=Query(mid+,enn,msegtr[x].rig,lef,rig)+msegtr[msegtr[x].rig].com*Jud(mid+,enn,lef,rig);
}
return ans;
}
int main()
{
int n,m,temp,cnt;
int lef,rig,sum;
char str[];
while(~scanf("%d %d",&n,&m))
{
Init(cnt);
for(int i=;i<=n;++i)
{
scanf("%d",&temp);
pre[i]=pre[i-]+temp;
}
for(int i=;i<m;++i)
{
scanf("%s",str);
if(str[]=='C')
{
scanf("%d %d %d",&lef,&rig,&sum);
Create(,n,root[cnt+],root[cnt],lef,rig,sum);
cnt++;
}
else if(str[]=='Q')
{
scanf("%d %d",&lef,&rig);
printf("%I64d\n",Query(,n,root[cnt],lef,rig)+pre[rig]-pre[lef-]);
}
else if(str[]=='H')
{
scanf("%d %d %d",&lef,&rig,&sum);
printf("%I64d\n",Query(,n,root[sum],lef,rig)+pre[rig]-pre[lef-]);
}
else
{
scanf("%d",&sum);
if(sum<cnt)
{
tot=root[sum+];
cnt=sum;//存储线段树,这样就代表摧毁了后面更新的树
}
}
}
}
return ;
}

HDU 4348 To the moon (主席树区间更新)的更多相关文章

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

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

  2. hdu 4348 To the moon 主席树区间更新

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Prob ...

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

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

  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 主席树

    题意: 给出一个长度为\(n(n \leq 10^5)\)的序列,最开始时间\(t=0\),支持下面几个操作: \(C \, l \, r \, d\):将区间\([l,r]\)每个数都加上\(d\) ...

  6. HDU 4348 主席树区间更新

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  7. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  8. 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步操作 思路: ...

  9. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

随机推荐

  1. Python类基础知识(面向对象基础)

    #首先 我们需要了解 面向过程是什么 面向对象是什么 我们为什么需要使用面向对象 面向过程:根据业务逻辑从上到下写垒代码 面向对象:根据代码对函数进行分类和封装 区别:解决问题的逻辑不同,但是都能解决 ...

  2. php学习笔记8--半边引号引发的问题

    前段时间重装了系统,后来说是又要用php,就重新搭建了apache+php+mysql的环境,由于之前搭建过好多次,感觉很easy,很快就搭建完成,然后写了下面的常用的测试环境的代码: <?ph ...

  3. dfs-求连通块

    状态:若为W则继续搜索 import java.util.Scanner; public class Main { static int n,m; static char[][] field; sta ...

  4. 巨蟒django之CRM3 添加和编辑客户&&公户和私户的展示和转换

    昨日内容回顾: day66 1. 内容回顾 1. 数据的展示 数据通过ORM查询出来 对象列表 QuerySet 1. 普通的字段 对象.字段名 ——> 数据库中的值 2. choices (( ...

  5. (转)IOS崩溃 异常处理(NSSetUncaughtExceptionHandler)

    iOS已发布应用中对异常信息捕获和处理 代码下载地址:http://download.csdn.net/detail/daiyelang/6740205 iOS开发中我们会遇到程序抛出异常退出的情况, ...

  6. MSVCRT.DLL Console I/O Bug(setlocale(LC_CTYPE, "Chinese_China.936"))

    I have been quite annoyed by a Windows bug that causes a huge number of open-source command-line too ...

  7. JS上传图片预览及图片限制

    HTML代码: <form action="__SELF__" method="post" enctype='multipart/form-data'&g ...

  8. python函数回顾:all()

    描述 all() 函数用于判断给定的可迭代参数 iterable 中的所有元素,是否不为 0.''.False 或者 iterable 为空,如果是返回 True,否则返回 False. 如果是空元组 ...

  9. grep和正则表达式参数

    一:grep参数 1,-n  :显示行号 2,-o  :只显示匹配的内容 3,-q  :静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容 4,-l  :如果匹配成功,则只将 ...

  10. pgAgent设定定时备份

    PostgreSQL定时自动备份 简介 PostgreSQL数据库中未提供数据库的定时备份功能,所以需要结合备份和定时job功能来共同实现. 这里我选取了2种定时job方式,crontab是Linux ...