可持久化栈学习笔记 | 题解 P6182 [USACO10OPEN]Time Travel S
简要题意
你需要维护一个栈,有 \(n\) 个操作,支持:
- 给定一个 \(x\),将 \(x\) 加入栈。
- 将一个元素出栈。
- 给定一个 \(x\),将当前栈回退到 第 \(x\) 操作前。
每一次操作结束后,你需要输出栈顶元素。如果当前栈是一个空栈,那么输出 \(-1\)。
数据保证操作合法,且 \(1 \le n \le 8 \times 10^{4}\)。
思路
据说本题存在 \(O(n)\) 做法,但是我不会,这里有一个 \(O(n\log n)\) 做法。
对于 回退 之类的字眼,我们肯定会想到可持久化,由于栈一般时用数组实现的,所以我们可以写一个可持久化数组。如果不会可持久化数组,请去做 模板题。
下面有一个用数组实现的栈的简要代码,对于分析很有帮助:
int stk[114514],t;
void push(int v){
stk[++t]=v;
}
void pop(){
t--;
}
int top(){
return (t==0)?(-1):(stk[t]);
}
我们可以考虑用可持久化数组来维护 stk,那么 \(t\) 怎么办?我们发现,\(t\) 需要是一个可持久化变量,可持久化变量不就是数组吗?于是我们直接使用数组 \(T_i\) 来表示第 \(i\) 次操作后栈顶指针 \(t\)。
整个代码时间复杂度和空间复杂度都是 \(O(n\log n)\) 的(可持久化的开销)。
代码
#include <bits/stdc++.h>
#define mid ((l+r)>>1)
using namespace std;
const int SIZE = 8e4+5;
struct{
int l,r,v;
}t[SIZE*25];
int top;
int root[SIZE*25];
int n;
int newnode(int i){
t[++top]=t[i];
return top;
}
int update(int i,int l,int r,int p,int val){
i=newnode(i);
if(l==r){
t[i].v=val;
return i;
}
if(p<=mid){
t[i].l=update(t[i].l,l,mid,p,val);
}
else{
t[i].r=update(t[i].r,mid+1,r,p,val);
}
return i;
}
int query(int i,int l,int r,int p){
if(l==r){
return t[i].v;
}
if(p<=mid){
return query(t[i].l,l,mid,p);
}
else{
return query(t[i].r,mid+1,r,p);
}
}
int stop[SIZE];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
root[i]=root[i-1];
stop[i]=stop[i-1];
char op;
int x;
cin>>op;
if(op=='a'){
cin>>x;
root[i]=update(root[i-1],1,n,(++stop[i]),x);
}
else if(op=='s'){
stop[i]--;
}
else{
cin>>x;
root[i]=root[x-1];
stop[i]=stop[x-1];
}
if(stop[i]!=0){
cout<<query(root[i],1,n,stop[i])<<'\n';
}
else{
cout<<-1<<'\n';
}
}
return 0;
}
跑了 \(113\) 毫秒,比 \(O(n)\) 的慢。
可持久化栈学习笔记 | 题解 P6182 [USACO10OPEN]Time Travel S的更多相关文章
- 可持久化trie学习笔记
其实很早之前就想学习可持久化trie,不过由于换队友等情况,还是优先去学数论和计算几何,今天突然心血来潮学了一发可持久化trie,感觉还是蛮简单的,不过由于自己很长时间没写过可持久化了,都快忘了是个什 ...
- PHP全栈学习笔记18
php基础知识,JavaScript,jQuery,ajax基础知识 linux基础知识,mysql数据库的基础与优化 程序设计,PHP框架基础知识,算法,逻辑思维,高并发 PHP基础知识 引用变量, ...
- PHP全栈学习笔记13
php与ajax技术 web2.0的到来,ajax逐渐成为主流,什么是ajax,ajax的开发模式,优点,使用技术.(ajax概述,ajax使用的技术,需要注意的 问题,在PHP应用ajax技术的应用 ...
- PHP全栈学习笔记12
php简介,php历史,php后端工程师职业前景,php技术方向,php后端工程师职业体系介绍. php是世界上使用最广泛的web开发语言,是超文本预处理器,是一种通用的开源脚本语言,语法吸收了c语言 ...
- PHP全栈学习笔记17
phpmyadmin教程 管理页进入phpmyadmin 打开C:\wamp\apps\phpmyadmin3.5.1下的配置文件:config.inc 修改密码 创建与修改数据库.数据表 字段类型 ...
- PHP全栈学习笔记16
<?php $fileName = "php大师.test.php"; //补充程序,显示文件名(不包括扩展名) $start = strrpos($fileName, &q ...
- PHP全栈学习笔记15
PHP标记风格 PHP一共支持4种标记风格 <?php echo "这是XML风格的标记"; ?> 脚本风格 <script language="php ...
- PHP全栈学习笔记14
一.搭建PHP开发环境 Apahce服务器 Dreamwear创建站点 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitiona ...
- PHP全栈学习笔记11
连接MySQL mysql_connect(servername,username,password); 面向对象: <?php $servername = "localhost&qu ...
- PHP全栈学习笔记10
php常量,常量是不能被改变的,由英文字母,下划线,和数字组成,但是数字不能作为首字母出现. bool define ( string $name , mixed $value [, bool $ca ...
随机推荐
- 齐博x1嵌套-循环栏目,并列出子栏目下的内容
嵌套,循环栏目,并列出子栏目下的内容. 代码如下: <div class="channel-list"> <div class="row"&g ...
- 【Odoo】Odoo16-性能优化提升
上海序说科技,专注于基于Odoo项目实施,实现企业数智化,助力企业成长. 老韩头的开发日常,博客园分享(2022年前博文) 10月12日,Odoo16版本正式发布,本文将就Odoo官方在性能方面做的优 ...
- 『现学现忘』Git分支 — 41、分支基本操作(二)
目录 6.新建一个分支并且使分支指向指定的提交对象 7.思考: 8.项目分叉历史的形成 9.分支的总结 提示:接上篇 6.新建一个分支并且使分支指向指定的提交对象 使用命令:git branch br ...
- 分布式ID生成方案总结整理
目录 1.为什么需要分布式ID? 2.业务系统对分布式ID有什么要求? 3.分布式ID生成方案 3.1 UUID 3.2.数据库自增 3.3.号段模式 3.4. Redis实现 3.4. 雪花算法(S ...
- SpringBoot(三) - Ribbon客户端负载均衡,Zuul网关,Config配置中心
1.Ribbon客户端负载均衡 1.1 依赖 1.2 配置信息 # feign默认加载了ribbon负载均衡,默认负载均衡机制是:轮询 # 负载均衡机制是添加在消费端(客户端)的,如果改为随机,指定服 ...
- PCA降维的原理及实现
PCA可以将数据从原来的向量空间映射到新的空间中.由于每次选择的都是方差最大的方向,所以往往经过前几个维度的划分后,之后的数据排列都非常紧密了, 我们可以舍弃这些维度从而实现降维 原理 内积 两个向量 ...
- Java 编码那些事(一)
编码 做Web的同学,最开始一定遇到过乱码问题,工作这么久,一定听说过Unicode, GB2312等编码.典型的记事本选择的四种选项:ANSI,Unicode,Unicode big endian, ...
- Abp.Zero 手机号免密登录验证与号码绑定功能的实现(一):验证码模块
这是一篇系列博文,我将使用Abp.Zero搭建一套集成手机号免密登录验证与号码绑定功能的用户系统: Abp.Zero 手机号免密登录验证与号码绑定功能的实现(一):验证码模块 Abp.Zero 手机号 ...
- 19_Vue如何监测到对象类型数据发生改变的?
数据更新 关于监视 我们之前讲过,我们在data当中配置的属性,最终会挂载在vue实例身上,而data这个配置项,最终也会在vue身上成为一个新的属性 == _data 当我们在页面DOM当中,去使用 ...
- Codeforces Round #802 (Div. 2)C. Helping the Nature(差分)
题目链接 题目大意: 给你一个有n个元素的数组a,你可以通过一下三种操作使数组的每一个值都为0: 选择一个下标i,然后让a[1],a[2]....a[ i ] 都减一; 选择一个下标i,然后让a[i] ...