Atcoder Beginner Contest 273E - Notebook 解题报告

Atcoder Beginner Contest 273E - Notebook 解题报告

1 题目链接

传送门

2 题目大意

题目:笔记本
题目大意:

有一个版本保存系统,共有 1 0 9 10^9 109 个版本,每个版本初始都为空列表,还需要维护一个列表(后称为“当前列表”)。
您需要实现如下四种操作:

  • ADD x:在当前列表的末尾添加 x x x
  • DELETE:如果当前列表非空,把当前列表的末尾最后一个数删除。否则,什么也不做。
  • SAVE x:把当前列表保存至第 x x x 版本(在此后完成的操作不会在第 x x x 版本中出现,而且保存后当前列表不清空)
  • LOAD x:把当前列表变成第 x x x 版本(直接赋值,而不是添加,而且保存后第 x x x 版本不清空)

给定 q q q 次操作,每次操作是以上四种操作,求每次操作后的当前列表的末尾最后一个数(若数组为空输出 − 1 -1 1)。

3 解法分析

首先考虑纯模拟。

显然一眼假,但是可以借鉴纯模拟的思路。

不难发现所有的版本都是由一个最远古的版本经过不断地修改得来的。

对比树,发现可以用树来模拟整个过程。

考虑用 c u r cur cur i d x idx idx 表示当前的最后一个点, f a [ c u r ] fa[cur] fa[cur] 表示上一个, v a l [ c u r ] val[cur] val[cur] 表示该点对应的数值, e [ i ] e[i] e[i] 用来存这棵树,且当有向图存,最后用 m p mp mp 来处理不同树枝上的跳转。

按照建树的过程模拟一下就结束了。

注意可以先将所有的 v a l [ i ] val[i] val[i] 赋初值 − 1 -1 1 ,这样就不用特判可以直接输出了。

完结撒花。

4 AC Code

#include <bits/stdc++.h>
#define rep(i, a, b) for (int (i) = (a); (i) <= (b); ++(i))
#define fep(i, a, b) for (int (i) = (a); (i) < (b); ++(i))
#define N 500007
using namespace std;

int x;
string ty;
int cur, idx;
int fa[N], val[N];
vector <int> e[N];
map <int, int> mp;

void solve() {
	cin >> ty;
	if (ty != "DELETE")
		scanf("%d", &x);
	if (ty == "ADD") {
		e[cur].push_back(++idx);
		val[idx] = x;
		fa[idx] = cur;
		cur = idx;
	}
	else if (ty == "DELETE")
		cur = fa[cur];
	else if (ty == "SAVE")
		mp[x] = cur;
	else if (ty == "LOAD")
		cur = mp[x];
	printf("%d ", val[cur]);
	return ;
}

int T;

int main() {
	fep(i, 0, N)
		val[i] = -1;
	scanf("%d", &T);
	while (T--)
		solve();
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值