题意

你需要维护一个任务列表,有 \(q\) 次操作,每次操作形如以下四种:

  • set a x:设置任务 \(a\) 的优先级为 \(x\),如果任务列表中没有 \(a\) 则加进来。

  • remove a:将任务 \(a\) 移除列表。

  • query a:求出有多少个任务的优先级比 \(a\) 的小,如果 \(a\) 不在列表里输出 \(-1\)。

  • undo d:撤销这次操作之前的 \(d\) 个操作。

注意撤销操作可以撤销之前的撤销操作

\(\texttt{Data Range:}1\leq q\leq 10^5,1\leq x\leq 10^9,1\leq\vert a\vert\leq 15\)

题解

我又是一个不看数据范围的屑 >_<

为什么这场的 D 比 E 还难写啊

好久没写可持久化数据结构了,来写个题解复习一下。

一看到什么撤销操作估计跟可持久化数据结构分不开了。

看到 query 操作其实可以开一棵可持久化权值线段树来维护一下,然后 set 的话需要一个可持久化数组来维护每个任务的优先级。

然后按照题意模拟就得了,因为这题的 \(x\leq 10^9\) 所以不写结构体式线段树可以免去建树的空间开销。

注意一下空间问题即可通过,这里可能要根据数据范围估算一下空间开销。

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51;
map<string,ll>mp;
ll n,totn,totid,x,id,p,limit=1e9;
string op,str;
ll rt[MAXN<<2],rt2[MAXN<<2],sm[MAXN<<6],ls[MAXN<<6],rs[MAXN<<6];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline ll getId(string s)
{
return mp.find(s)==mp.end()?mp[s]=++totid:mp[s];
}
inline void update(ll node)
{
sm[node]=sm[ls[node]]+sm[rs[node]];
}
inline ll add(ll l,ll r,ll pos,ll val,ll node)
{
ll cur=++totn;
ls[cur]=ls[node],rs[cur]=rs[node];
if(l==r)
{
return sm[cur]=sm[node]+val,cur;
}
ll mid=(l+r)>>1;
if(pos<=mid)
{
ls[cur]=add(l,mid,pos,val,ls[node]);
}
else
{
rs[cur]=add(mid+1,r,pos,val,rs[node]);
}
return update(cur),cur;
}
inline ll query(ll l,ll r,ll ql,ll qr,ll node)
{
if(ql<=l&&qr>=r)
{
return sm[node];
}
ll mid=(l+r)>>1,res=0;
res+=ql<=mid?query(l,mid,ql,qr,ls[node]):0;
res+=qr>mid?query(mid+1,r,ql,qr,rs[node]):0;
return res;
}
int main()
{
n=read();
for(register int i=1;i<=n;i++)
{
cin>>op,rt[i]=rt[i-1],rt2[i]=rt2[i-1];
if(op=="set")
{
cin>>str,x=read(),id=getId(str),p=query(1,limit,id,id,rt2[i]);
p?rt[i]=add(1,limit,p,-1,rt[i]):1;
rt[i]=add(1,limit,x,1,rt[i]),rt2[i]=add(1,limit,id,x-p,rt2[i]);
}
if(op=="remove")
{
cin>>str,id=getId(str),p=query(1,limit,id,id,rt2[i]);
p?rt[i]=add(1,limit,p,-1,rt[i]):1,rt2[i]=add(1,limit,id,-p,rt2[i]);
}
if(op=="undo")
{
x=read(),rt[i]=rt[i-x-1],rt2[i]=rt2[i-x-1];
}
if(op=="query")
{
cin>>str,id=getId(str),p=query(1,limit,id,id,rt2[i]);
cout<<(p==0||p==1?p-1:query(1,limit,1,p-1,rt[i]))<<endl;
}
}
}

CodeForces 916D Jamie and To-do List的更多相关文章

  1. CodeForces 916E Jamie and Tree(树链剖分+LCA)

    To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...

  2. Codeforces 916C - Jamie and Interesting Graph

    916C - Jamie and Interesting Graph 思路:构造. 对于1到n最短路且素数,那么1到n之间连2 对于最小生成树,找一个稍微大点的素数(比1e5大)构造一个和为这个素数的 ...

  3. Codeforces 916E Jamie and Tree (换根讨论)

    题目链接  Jamie and Tree 题意  给定一棵树,现在有下列操作: $1$.把当前的根换成$v$:$2$.找到最小的同时包含$u$和$v$的子树,然后把这棵子树里面的所有点的值加$x$: ...

  4. codeforces 916E Jamie and Tree dfs序列化+线段树+LCA

    E. Jamie and Tree time limit per test 2.5 seconds memory limit per test 256 megabytes input standard ...

  5. CodeForces 916C Jamie and Interesting Graph (构造)

    题意:给定两个数,表示一个图的点数和边数,让你构造出一个图满足 1-  n 的最短路是素数,并且最小生成树也是素数. 析:首先 1 - n 的最短路,非常好解决,直接 1 连 n 就好了,但是素数尽量 ...

  6. CodeForces 916B Jamie and Binary Sequence (changed after round) (贪心)

    题意:给定两个数字n,m,让你把数字 n 拆成一个长度为 m 的序列a1,a2,a3...am,并且∑2^ai = n,如果有多组,要求序列中最大的数最小,然后再相同就要求除了最大数字典序最大. 析: ...

  7. CodeForces 916A Jamie and Alarm Snooze (水题)

    题意:给定一个数字n,和一个时间,问你每次可以把当前时间往回调n分钟,然后调多少次后时间中包含数字7. 析:直接模拟就好,从当前分钟向后调,注意调成负数的情况就好.很简单. 代码如下: #pragma ...

  8. Codeforces 916B - Jamie and Binary Sequence (changed after round)

    思路: 先取出二进制的每一位,判断总个数是不是小于等于k,如果大于k则不能构成. 通过观察可以发现,每一位的一个可以转换成下一位的两个,因为要使最大位尽可能小,所以如果最大位的所有的个数都可以转换成下 ...

  9. Codeforces 916B Jamie and Binary Sequence ( 模拟 && 思维 )

    题意 : 给出一个数 n ,要求你用 k 个二的幂来组成这个数,要求输出这 k 个二的幂的指数,如果有多解情况则优先输出最大指数最小的那一个且要求按字典序输出,不存在则输出 No 分析 :  先来说一 ...

随机推荐

  1. RestTemplate get请求多参数 简单封装

    使用RestTemplate发送get请求时,如果有多个参数拼接起来会比较麻烦,在此做个简单的封装 public static void main(String[] args) { Map<St ...

  2. 电商订单ElasticSearch同步解决方案--使用logstash

    一.使用logstash同步订单数据(订单表和订单项表)到ElasticSearch: 1.到官网下载logstash:https://www.elastic.co/cn/downloads/logs ...

  3. 搭建 Spring 源码阅读环境

    前言 有一个Spring源码阅读环境是学习Spring的基础.笔者借鉴了网上很多搭建环境的方法,也尝试了很多,接下来总结两种个人认为比较简便实用的方法.读者可根据自己的需要自行选择. 方法一:搭建基础 ...

  4. interp1一维数据插值在matlab中的用法

    转载:https://ww2.mathworks.cn/help/matlab/ref/interp1.html?s_tid=srchtitle#btwp6lt-2_1 interp1 一维数据插值( ...

  5. #ifdef _DEBUG #define new DEBUG_NEW #endif的解释

    转载:https://blog.csdn.net/sinat_20265495/article/details/51762738 在用vc时,利用AppWizard会产生如下代码:#ifdef _DE ...

  6. Talk is cheap. Show me the code的由来

    Date: Fri, 25 Aug 2000 11:09:12 -0700 (PDT) From:Linus Torvalds Subject Re: SCO: "thread creati ...

  7. Oracle 正确删除归档日志的方法

    我们都知道在controlfile中记录着每一个archivelog文件的相关信息,当然们在OS下把这些物理文件delete掉后,在我们的controlfile中仍然记录着这些archivelog文件 ...

  8. golang执行exec命令

    创建对象: cmd, err := exec.Command("echo", "show me")   执行命令: cmd.Run()  //Run 阻塞进程, ...

  9. MeteoInfoLab脚本示例:SeaWiFS HDF Grid数据

    SeaWiFS HDF Grid数据读取,特别是涉及到了文件的众多属性数据的读取,数据取对数后绘图.脚本程序: #Add data file f = addfile('D:/Temp/hdf/S199 ...

  10. C++ concurrent_queue

    ConcurrentQueue 用C++11提供的多线程类实现一个线程安全的队列: #include <queue> #include <mutex> #include < ...