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 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
随机推荐
- SSL证书的生成
openssl工具下载路径:链接:https://pan.baidu.com/s/1o0-s8OplHZt55Cio2HmjVA 密码:u759 1.使用openssl工具生成一个RSA秘钥 ...
- 【BZOJ4974】字符串大师 KMP
[BZOJ4974]字符串大师 Description 一个串T是S的循环节,当且仅当存在正整数k,使得S是T^k(即T重复k次)的前缀,比如abcd是abcdabcdab的循环节.给定一个长度为n的 ...
- Cocos2d-x Lua中多场景切换生命周期
在多个场景切换时候,场景的生命周期会更加复杂.这一节我们介绍一下场景切换生命周期.多个场景切换时候分为几种情况:情况1,使用pushScene函数从实现GameScene场景进入SettingScen ...
- Digit Division
Digit Division Time limit: 1 s Memory limit: 512 MiB We are given a sequence of n decimal digits. Th ...
- 安装IntelliJ IDEA 破解安装
IDEA 功能介绍 1-深度智力 IntelliJ IDEA为您的源代码编制索引后,通过在每个环境中提供相关建议,提供快速,智能的体验:即时和智能的代码完成,即时代码分析和可靠的重构工具. 2-开箱即 ...
- C#窗体传值
整理一下: 1.静态变量传值,非常简单适合简单的非实例的 public calss form1:Form{ public static int A; } public class form2:Form ...
- 搭建Spring所需的各类jar包汇总详解
Spring jar包官网下载地址:http://repo.spring.io/release/org/springframework/spring/ Spring jar包的描述:针对3.2.2以上 ...
- JavaWeb 过滤器应用之页面静态化
页面静态化是把servlet请求的资源所做输出保存到html中, 然后重定向到 html 页面, 二次访问时,这个html已经存在,那么直接重定向,不用再去访问servlet! // StaticFi ...
- 如何生成动态库 .dll 的符号 .lib 文件?
在知道拥有动态库和头文件的情况下,但没有动态库符号文件的情况下,如何静态链接动态库? 1.使用 Microsoft Visual Studio Tools 命令行命令生成 xxx.def 文件,进而使 ...
- make编译三
多目标 Makefile 的规则中的目标可以不止一个,其支持多目标,有可能我们的多个目标同时依赖于一个文件,并且其生成的命令大体类似.于是我们就能把其合并起来.但是如果多个目标的生成规则的执行命令是同 ...