浅谈主席树:https://www.cnblogs.com/AKMer/p/9956734.html

浅谈标记永久化:https://www.cnblogs.com/AKMer/p/10137227.html

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4348

相比一般的主席树,这个要多支持一个操作,那就是区间修改。我们不能把区间里的每一条链都建出来,因为那样时间空间都不允许,所以我们可以依靠标记永久化来实现。每次询问的时候,把一路上的标记全部累加起来,再计算对当前区间答案的影响就好了。

时间复杂度:\(O((n+m)logn)\)

空间复杂度:\(O((n+m)logn)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll; const int maxn=1e5+5; char s[10];
int n,m,tim;
int a[maxn],rt[maxn]; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct tree_node {
ll sum;
int ls,rs,tag;
}; struct Chairman_tree {
int tot;
tree_node tree[maxn*30]; void updata(int p) {
tree[p].sum=tree[tree[p].ls].sum+tree[tree[p].rs].sum;
} void build(int &now,int l,int r) {
now=++tot;tree[now].tag=0;
if(l==r) {
tree[now].sum=a[l];
tree[now].ls=tree[now].rs=0;
return;
}
int mid=(l+r)>>1;
build(tree[now].ls,l,mid);
build(tree[now].rs,mid+1,r);
updata(now);
} void change(int lst,int &now,int l,int r,int L,int R,int v) {
now=++tot;tree[now]=tree[lst];
tree[now].sum+=1ll*(min(r,R)-max(l,L)+1)*v;//记得要一路修改下去
//如果调用updata函数用儿子节点更新自己的值,可能会用没被标记影响的上一个版本的主席树的儿子来更新自己
if(L<=l&&r<=R) {
tree[now].tag+=v;
return;
}
int mid=(l+r)>>1;
if(L<=mid)change(tree[lst].ls,tree[now].ls,l,mid,L,R,v);
if(R>mid)change(tree[lst].rs,tree[now].rs,mid+1,r,L,R,v);
} ll query(int now,int l,int r,int L,int R,int res) {
if(L<=l&&r<=R)return tree[now].sum+1ll*(r-l+1)*res;
int mid=(l+r)>>1;ll val=0;
if(L<=mid)val+=query(tree[now].ls,l,mid,L,R,res+tree[now].tag);
if(R>mid)val+=query(tree[now].rs,mid+1,r,L,R,res+tree[now].tag);
return val;
}
}T; int main() {
while(~scanf("%d%d",&n,&m)) {
tim=T.tot=0;
for(int i=1;i<=n;i++)
a[i]=read();
T.build(rt[0],1,n);
for(int i=1;i<=m;i++) {
scanf("%s",s+1);
if(s[1]=='C') {
tim++;int l=read(),r=read(),d=read();
T.change(rt[tim-1],rt[tim],1,n,l,r,d);
}
else if(s[1]=='Q') {
int l=read(),r=read();
ll ans=T.query(rt[tim],1,n,l,r,0);
printf("%lld\n",ans);
}
else if(s[1]=='H') {
int l=read(),r=read(),t=read();
ll ans=T.query(rt[t],1,n,l,r,0);
printf("%lld\n",ans);
}
else if(s[1]=='B') {
int t=read();
tim=t;T.tot=rt[tim+1];
}
}
}
return 0;
}

HDU4348:To the moon的更多相关文章

  1. SPOJ:To the moon

    题面 vjudge Sol 主席树模板 # include <bits/stdc++.h> # define RG register # define IL inline # define ...

  2. Moon.Orm 5.0(MQL版)及之前版本的开源计划

    开源综述:步步开源 Moon.Orm 5.0 (MQL版) 版本维护及下载 (跟踪发布) Moon.Orm 5.0系列文章 Moon.Orm 5.0性能问题,将发言权交给你! 一.5.0目前的情况,步 ...

  3. Moon.Orm 5.0 (MQL版)

    Moon.Orm 5.0 (MQL版) 实战实例Moon.Orm 5.0 革命性的设计 打造最便捷的异步分页技术(提供下载) 摘要: 一.建一个项目(以WebForm为例)配置文件配置(注意您自己的路 ...

  4. JS教程:从0开始

    一. JS简介 1. JavaScript概述 JavaScript 是世界上最流行的编程语言.这门语言可用于 HTML 和 web,更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备. ...

  5. 前端每日实战:36# 视频演示如何利用 CSS 动画原理,在页面上表现日蚀现象

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教程 此视频 ...

  6. Java牛角尖【007】:Java中的Error能不能被Catch

      Java牛角尖[007]:Java中的Error能不能被Catch 网上看到很多朋友说Java中Error是无法Catch到的,而Java中定义的Error类型又很难测试到,那就估且以为确是如此吧 ...

  7. 前端每日实战:55# 视频演示如何用纯 CSS 创作一个太阳、地球、月亮的运转模型

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/RJjQYY 可交互视频 此视频是可 ...

  8. python 爬虫1

    简单访问有道词典的翻译界面,将页面翻译功能简单呈现 import urllib.request import urllib.parse import json content = input(&quo ...

  9. Linux字符界面下用户账户的设置

    在Linux系统字符界面下创建.修改以及删除用户账户主要使用useradd,usermod和userdel这3个命令. 一.创建用户账户 创建用户账户就是在系统中创建一个新账户,然后为新账户分配用户U ...

随机推荐

  1. SVN 等版本管理工具

    程序猿团队开发代码,必须的程序版本管理工具 1.SVN使用教程总结 2.SVN如何切换用户 在使用svn更新或提交数据时需要输入用户名和密码,在输入框中可以选择是否记录,以便下次操作无需再次输入用户名 ...

  2. 如何编译文件(gcc + nasm)

    [0]README 编译文件(nasm + gcc),特别是编译目标文件的依赖文件:本文旨在回顾 gcc 和 nams 编译器的编译命令,以及如果有多个依赖文件该如何编译: [1]编译文件 1.1)编 ...

  3. 解决pod search出来的库不是最新

    为了让CocoaPods的引入不显示警告,在Podfile最上方加上: inhibit_all_warnings! pod search 一些第三方SDK,发现并不是最新版本,那是因为你的本地repo ...

  4. JS基础常识理解

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Paxos is Simple

    [角色]0-MainProposer提案生成者1-提案发送者(MainProposer+OtherProposer)2-提案接收者(Acceptor)[动作]0-MainProposer----> ...

  6. 一起来学linux:SAMBA服务器搭建

    前面介绍的NFS服务器的用来linux和linux系统之间共享文件和目录的,那如果是linux和windows之间需要共享修改文件该如何操作呢.这据需要用到SAMBA系统.我们首先来看下SAMBA系统 ...

  7. Nginx Cache中$request_filename(转)

    对于Nginx的$request_filename变量指的就是请求的资源路径.在原先 OpenCDN节点端配置里面是这样的. location ~ .*\.(png|html|htm|ico|jpg| ...

  8. SAP-Function

    [转]sap函数大全 ********SAP中常用函数 函数名 描述SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息EDIT_LINES 把READ_TEXT返回的L ...

  9. linux下chrome和chromedriver的安装

    1.安装chrome 用下面的命令安装最新的 Google Chrome yum install https://dl.google.com/linux/direct/google-chrome-st ...

  10. Java多线程系列 基础篇05 synchronized关键字

    1. synchronized原理 在java中,每一个对象有且仅有一个同步锁,所以同步锁是依赖于对象而存在.当我们调用某对象的synchronized方法时,就获取了该对象的同步锁.例如,synch ...