题解:CF916D Jamie and To-do List
题意
维护一个数据结构,支持以下几种操作:
set ai xi
:设置任务的优先级为 ,如果该列表中没有出现则加入该任务。 remove a_i
:删除该任务。query a_i
:求优先级比小的任务个数,如果没有则输出 。 undo sum
:删除此次操作之前的次操作。
分析
前三个操作是非常典型的平衡树操作,考虑使用平衡树或者动态开点线段树。
第四个带撤回,考虑使用可持久化数据结构。
本篇题解使用可持久化动态开点线段树解决。
维护两棵线段树,一棵维护区间和用于记录优先级,一棵维护某任务是否存在。
注意本题强制在线,其他的内容就是板子。
Code
#include<bits/stdc++.h> using namespace std; namespace SegT { struct node { int sum; node *lc, *rc; node() {memset(this, 0, sizeof *this);} void push_up() { sum=0; if(lc) sum+=lc->sum; if(rc) sum+=rc->sum; } }; #define lc(x) (x?x->lc:0) #define rc(x) (x?x->rc:0) #define mid ((l+r)>>1) #define lson x->lc, l, mid #define rson x->rc, mid+1, r void modify(node *pre, node *&x, int l, int r, int p, int v) { x=pre?new node(*pre):new node; if(l==r) return x->sum+=v, void(); if(p<=mid) modify(lc(pre), lson, p, v); if(p>mid) modify(rc(pre), rson, p, v); x->push_up(); } int query(node *x, int l, int r, int L, int R) { if(!x) return 0; if(L<=l&&r<=R) return x->sum; int ret=0; if(L<=mid) ret+=query(lson, L, R); if(R>mid) ret+=query(rson, L, R); return ret; } } namespace SegT2 { struct node { int v; node *lc, *rc; node() {memset(this, 0, sizeof *this);} }; void build(node *&x, int l, int r) { x=new node; if(l==r) return; build(lson); build(rson); } void modify(node *pre, node *&x, int l, int r, int p, int v) { x=new node(*pre); if(l==r) return x->v=v, void(); if(p<=mid) modify(pre->lc, lson, p, v); if(p>mid) modify(pre->rc, rson, p, v); } int query(node *x, int l, int r, int p) { if(l==r) return x->v; if(p<=mid) return query(lson, p); if(p>mid) return query(rson, p); } } unordered_map<string, int> ids; SegT::node *rt[100005]; SegT2::node *exist[100005]; int main() { ios::sync_with_stdio(0); int q, xi; const int n=1e9, m=1e5; cin>>q; string s, op; build(exist[0], 1, m); for(int i=1;i<=q;i++) { rt[i]=rt[i-1]; exist[i]=exist[i-1]; cin>>op; if(op[0]=='u') { cin>>xi; rt[i]=rt[i-1-xi]; exist[i]=exist[i-1-xi]; } else { cin>>s; if(!ids.count(s)) ids[s]=ids.size()+1; int a=ids[s]; if(op[0]=='s') { cin>>xi; int va=query(exist[i], 1, m, a); if(va) modify(rt[i], rt[i], 1, n, va, -1); modify(exist[i], exist[i], 1, m, a, xi); modify(rt[i], rt[i], 1, n, xi, 1); } if(op[0]=='q') { int ans=0; int va=query(exist[i], 1, m, a); if(va>1) ans=query(rt[i], 1, n, 1, va-1); if(!va) ans=-1; cout<<ans<<endl; } if(op[0]=='r') { int va=query(exist[i], 1, m, a); if(!va) continue; modify(rt[i], rt[i], 1, n, va, -1); modify(exist[i], exist[i], 1, m, a, 0); } } } }
本文作者:Jimmy-LEEE
本文链接:https://www.cnblogs.com/redacted-area/p/18389459
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步