题意

你需要维护一个任务列表,有 \(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. You must give at least one requirement to install (see "pip help install")

    语言: python why? install 后面没有参数,也就是说没有给想要安装的包 way? pip install 后面要跟想要安装的包名

  2. Optimisation

    https://www.cnblogs.com/wuyudong/p/writing-efficient-c-and-code-optimization.html 1 不要过多使用 stack ,尽量 ...

  3. Jetson AGX Xavier/Ubuntu安装QT

    安装QT命令 sudo apt-get install qt5-default qtcreator -y 如果出现错误:unknow module webenginewidgets serialpor ...

  4. C++ 中explicit的作用

    转载:https://www.cnblogs.com/diligenceday/p/5781408.html C++ 中explicit的作用   explicit作用: 在C++中,explicit ...

  5. GetPrivateProfileString

    参考: 1. https://blog.csdn.net/tunnel115/article/details/3081340 2. https://blog.csdn.net/hopedream200 ...

  6. 从0到1进行Spark history分析

    一.总体思路 以上是我在平时工作中分析spark程序报错以及性能问题时的一般步骤.当然,首先说明一下,以上分析步骤是基于企业级大数据平台,该平台会抹平很多开发难度,比如会有调度日志(spark-sub ...

  7. ubuntu19.10如何设置固定ip

    $ip a 看见系统中有两块网卡 lo: ...... ens33: ...... #cd /etc/netplan$ls目录下面有文件01-network-manager-all.yaml $sud ...

  8. TMS, XYZ & WMTS的不同

    WMS是OGC定义的协议,用于请求任意区域的渲染地图图像.客户可以根据需要以平铺模式对其进行请求. WMS-C是OSGeo创建的WMS扩展,它向功能文档中添加了元数据,以使客户端知道在哪里发出请求,从 ...

  9. Cesium资料

    CesiumLab论坛:https://github.com/cesiumlab/cesium-lab-forum/issues简书上的Cesium实验室文集:https://www.jianshu. ...

  10. 试用 Azure Sql 数据库

    我们的12月试用账号的免费服务里有一个Azure Sql服务,最近正好自己做一个小工具需要一个数据库,正好可以把它当测试库顺便体验一把Azure Sql. 概述 Azure SQL 数据库 Azure ...