题意
维护一个数据结构,支持以下几种操作:
set ai xi
:设置任务 \(a_i\) 的优先级为 \(x_i\),如果该列表中没有出现则加入该任务。remove a_i
:删除该任务。query a_i
:求优先级比 \(a_i\) 小的任务个数,如果没有则输出 \(-1\)。undo sum
:删除此次操作之前的 \(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);
}
}
}
}
标签:node,rt,int,题解,sum,Jamie,List,rc,query
From: https://www.cnblogs.com/redacted-area/p/18389459