题目大意是给出一些操作,支持删除插入查找一些值,就是动态维护一些值。
分析:不想写splay感觉有点难写虽然听WQS说splay好处多多,所以同treap来了一发,删除的时候发现当前节点不行就直接删除左子树全部就行啦,没有单点删除感觉还是萌萌哒很快就能写出来哒,树内放的是与基准值delta的差值哦
恶补数据结构第一站treap。
#include<iostream> #include<cstdio> #include<cstdlib> #include<ctime> #define N 100005 using namespace std; int ra[N],ls[N],rs[N],root,siz[N],key[N]; int n,m,delta,ans,len; void push(int k) { siz[k]=siz[ls[k]]+siz[rs[k]]+1; } void rturn(int &k) { int t=ls[k]; ls[k]=rs[t]; rs[t]=k; siz[t]=siz[k]; push(k); k=t; } void lturn(int &k) { int t=rs[k]; rs[k]=ls[t]; ls[t]=k; siz[t]=siz[k]; push(k); k=t; } void ins(int &k,int val) { if (k==0) { k=++len; ra[k]=rand(); key[k]=val; siz[k]=1; return; } siz[k]++; if (val<key[k]) { ins(ls[k],val); if (ra[k]>ra[ls[k]]) rturn(k); } else { ins(rs[k],val); if (ra[k]>ra[rs[k]]) lturn(k); } } int del(int &k,int x) { if (!k) return 0; int t; if (x>key[k]) { t=siz[ls[k]]+1; k=rs[k]; return t+del(k,x); } else { t=del(ls[k],x); siz[k]-=t; return t; } } int findd(int k,int x) { if (siz[ls[k]]+1==x) return key[k]; if (siz[ls[k]]+1<x) return findd(rs[k],x-siz[ls[k]]-1); else return findd(ls[k],x); } int main() { char op[1];int x; scanf("%d%d",&n,&m); while (n--) { scanf("%s%d",op,&x); if (op[0]=='I') if (x>=m) ins(root,x-delta); if (op[0]=='A') delta+=x; if (op[0]=='S') {delta-=x;ans+=del(root,m-delta);} if (op[0]=='F') { if (x>siz[root]) printf("-1\n"); else printf("%d\n",findd(root,siz[root]-x+1)+delta); } }printf("%d\n",ans); return 0; }