HDU 4348 To the moon (主席树区间更新)
题意:首先给你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 (主席树区间更新)的更多相关文章
- hdu 4348 To the moon (主席树区间更新)
传送门 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q l r:查询当前时间戳区间[l,r]中所有数的和 . (3)H ...
- hdu 4348 To the moon 主席树区间更新
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Prob ...
- HDU 4348 To the moon 主席树 在线更新
http://acm.hdu.edu.cn/showproblem.php?pid=4348 以前做的主席树没有做过在线修改的题做一下(主席树这种东西正经用法难道不是在线修改吗),标记永久化比较方便. ...
- hdu 4348 To the moon (主席树)
版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4348 题意: 一个长度为n的数组,4种操作 : (1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 . (2)Q ...
- HDU 4348 To the moon 主席树
题意: 给出一个长度为\(n(n \leq 10^5)\)的序列,最开始时间\(t=0\),支持下面几个操作: \(C \, l \, r \, d\):将区间\([l,r]\)每个数都加上\(d\) ...
- HDU 4348 主席树区间更新
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- 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步操作 思路: ...
- HDU 1556 Color the ball(线段树区间更新)
Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
随机推荐
- 《从零开始学Swift》学习笔记(Day 20)——函数中参数的传递引用
原创文章,欢迎转载.转载请注明:关东升的博客 参数的传递引用 类是引用类型,其他的数据类型如整型.浮点型.布尔型.字符.字符串.元组.集合.枚举和结构体全部是值类型. 有的时候就是要将一个值类型参数以 ...
- Genealogical tree
Genealogical tree Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6032 Accepted: 3973 Spec ...
- [python数据结构] hashable, list, tuple, set, frozenset
学习 cs212 unit4 时遇到了 tuple, list, set 同时使用的问题,并且进行了拼接.合并操作.于是我就被弄混了.所以在这里进行一下总结. hashable and unhasha ...
- ssm框架整合-过程总结(第三次周总结)
本周主要是完成前端界面和后端的整合. 犹豫前后端的工作完成程度不一致,只实现了部分整合. 登录界面. 可能自己最近没有把重心放在短学期的项目上,导致我们工作的总体进度都要比别慢. 虽然我们只是三个人的 ...
- Vue中浏览器的的前进和后退
项目开发的时候,有时候可能需要我们来对页面后退和前进,这个东西跟浏览器自带的前进后退功能很像,下面来大致讲一下在vue中浏览器的前进和后退 一.后退功能 vue中的后退有好多种方法可以使用,使用这些方 ...
- Django 之 CBV & FBV
FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django随笔中,一直使用的是这种方式,不再赘述. CBV CBV(class base views) ...
- RabbitMQ_消息队列基本使用_2
简介 RabbitMQ:接受消息再传递消息,可以视为一个“邮局”. 发送者和接受者通过队列来进行交互,队列的大小可以视为无限的,多个发送者可以发生给一个队列,多个接收者也可以从一个队列中接受消息. p ...
- (3.2)mysqldump之备份单个表及脚本批量备份
单库单表备份通用格式 mysqldump -uroot -p123456 test1 char_1>/opt/mysql_test1_char1.sql 分析:这里test1是库名,char_ ...
- 017-Hadoop Hive sql语法详解7-去重排序、数据倾斜
一.数据去重排序 1.1.去重 distinct与group by 尽量避免使用distinct进行排重,特别是大表操作,用group by代替 -- 不建议 select DISTINCT key ...
- 如何高效地分析Android_log中的问题?——查看Android源码
在日常解bugs时,需要通过log日志来分析问题,例如查看crash发生时的堆栈信息时,就会有Android的源码的调用,这是就要去查看Android源码. 1.进入Android源码网址查看,例如 ...