P1383 高级打字机(可持续化线段树)

2024-03-26 13:44

本文主要是介绍P1383 高级打字机(可持续化线段树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。

请为这种高级打字机设计一个程序,支持如下 33 种操作:

  1. T x:Type 操作,表示在文章末尾打下一个小写字母 x。
  2. U x:Undo 操作,表示撤销最后的 x 次修改操作。
  3. Q x:Query 操作,表示询问当前文章中第 x 个字母并输出。请注意 Query 操作并不算修改操作。

文章一开始可以视为空串。

输入格式

第 11 行:一个整数 n,表示操作数量。

以下 n 行,每行一个命令。保证输入的命令合法。

输出格式

每行输出一个字母,表示 Query 操作的答案。

输入输出样例

输入 #1复制

7
T a
T b
T c
Q 2
U 2
T c
Q 2

输出 #1复制

b
c
解析:

用可持续化线段树,每次操作的区间的最后一个没有记录的为1个区间。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;const int N = 100005;
#define mid ((l+r)>>1)
int root[N],tot = 0,cnt = 0;
int ls[N*20],rs[N*20],sum[N*20];
char ch[N*20];void pushup(int u)
{sum[u] = sum[ls[u]] + sum[rs[u]];	
} void change(int &u,int v,int l,int r,char c)
{u =++tot;ls[u] = ls[v];rs[u] = rs[v];sum[u] = sum[v];if(l==r){sum[u] = 1;ch[u] = c;return;}if(sum[ls[u]] < mid - l+1) change(ls[u],ls[v],l,mid,c); // 左区间的字母树是否小于 左区间 的 宽度else change(rs[u],rs[v],mid+1,r,c);pushup(u);
}char query(int u,int l,int r,int x)//查询第x个字母 
{if(l == r) return ch[u];if(x <= sum[ls[u]]) return query(ls[u],l,mid,x);else return query(rs[u],mid+1,r,x-sum[ls[u]]);
}int main()
{int n;cin >> n;for(int i = 1;i <= n;i++){char o,c;int x;cin >> o;if(o == 'T'){cin >> c;++cnt;change(root[cnt],root[cnt-1],1,n,c);}if(o == 'U'){cin >> x;++cnt;root[cnt] = root[cnt-x-1];}if(o == 'Q'){cin>>x;cout<<query(root[cnt],1,n,x)<<endl;}} return 0;
}

 时间复杂度为:O(n*longn)

这篇关于P1383 高级打字机(可持续化线段树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/848701

相关文章

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine

Docker部署Jenkins持续集成(CI)工具的实现

《Docker部署Jenkins持续集成(CI)工具的实现》Jenkins是一个流行的开源自动化工具,广泛应用于持续集成(CI)和持续交付(CD)的环境中,本文介绍了使用Docker部署Jenkins... 目录前言一、准备工作二、设置变量和目录结构三、配置 docker 权限和网络四、启动 Jenkins

深入解析Spring TransactionTemplate 高级用法(示例代码)

《深入解析SpringTransactionTemplate高级用法(示例代码)》TransactionTemplate是Spring框架中一个强大的工具,它允许开发者以编程方式控制事务,通过... 目录1. TransactionTemplate 的核心概念2. 核心接口和类3. TransactionT

Python中列表的高级索引技巧分享

《Python中列表的高级索引技巧分享》列表是Python中最常用的数据结构之一,它允许你存储多个元素,并且可以通过索引来访问这些元素,本文将带你深入了解Python列表的高级索引技巧,希望对... 目录1.基本索引2.切片3.负数索引切片4.步长5.多维列表6.列表解析7.切片赋值8.删除元素9.反转列表

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while