题目链接
题意:
写一种数据结构,来维护一些数,其中需要提供以下操作:
- 插入 xx 数
- 删除 xx 数(若有多个相同的数,因只删除一个)
- 查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
- 查询排名为 xx 的数
- 求 xx 的前驱(前驱定义为小于 xx,且最大的数)
- 求 xx 的后继(后继定义为大于 xx,且最小的数)
题解:
平衡树的模板题,但是treap相较于其他的BST更好写、更好理解
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<algorithm>
#include<cstdio>
#include<list>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))
const int mod = 1e9+7;
using namespace std;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
#define endl '\n'
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
const int maxn = 1e3+10;
struct node{
int l,r;
int val,key;
int sz;
}fhq[N];
int cnt,root;
mt19937 rng(time(NULL));
int newnode(int val){
fhq[++cnt].val=val;
fhq[cnt].key=rng();//给每个节点随机分配一个优先级
fhq[cnt].sz=1;
return cnt;
}
void update(int now){
fhq[now].sz=fhq[fhq[now].l].sz+fhq[fhq[now].r].sz+1;
}
void split(int now,int val,int &x,int &y){
if(!now) x=y=0;
else{
if(fhq[now].val<=val){
x=now;
split(fhq[now].r,val,fhq[now].r,y);
}
else{
y=now;
split(fhq[now].l,val,x,fhq[now].l);
}
update(now);
}
}
int merge(int x,int y){
if(!x||!y) return x+y;
if(fhq[x].key>fhq[y].key){
fhq[x].r=merge(fhq[x].r,y);
update(x);
return x;
}
else{
fhq[y].l=merge(x,fhq[y].l);
update(y);
return y;
}
}
int x,y,z;
void ins(int val){
split(root,val,x,y);
root=merge(merge(x,newnode(val)),y);
}
void del(int val){
split(root,val,x,z);
split(x,val-1,x,y);
y=merge(fhq[y].l,fhq[y].r);
root=merge(merge(x,y),z);
}
void getrank(int val){
split(root,val-1,x,y);
cout<<fhq[x].sz+1<<endl;
root=merge(x,y);
}
void getnum(int rank){
int now=root;
while(now){
if(fhq[fhq[now].l].sz+1==rank)
break;
else if(fhq[fhq[now].l].sz>=rank)
now=fhq[now].l;
else {
rank-=fhq[fhq[now].l].sz+1;
now=fhq[now].r;
}
}
cout<<fhq[now].val<<endl;
}
void pre(int val){
split(root,val-1,x,y);
int now = x;
while(fhq[now].r) now=fhq[now].r;
cout<<fhq[now].val<<endl;
root=merge(x,y);
}
void nxt(int val){
split(root,val,x,y);
int now=y;
while(fhq[now].l) now=fhq[now].l;
cout<<fhq[now].val<<endl;
root=merge(x,y);
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t; cin>>t;
while(t--){
int opt,x;cin>>opt>>x;
if(opt==1)ins(x);
if(opt==2)del(x);
if(opt==3)getrank(x);
if(opt==4)getnum(x);
if(opt==5)pre(x);
if(opt==6)nxt(x);
}
}
Splay好难写啊。。。
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<algorithm>
#include<cstdio>
#include<list>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;
#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))
const int mod = 1e9+7;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
struct node{
int ch[2];
int fa,val,siz;
}spy[N];
int cnt,root;
void update(int x){ spy[x].siz=spy[spy[x].ch[0]].siz+spy[spy[x].ch[1]].siz+1; }
bool ident(int x,int f){ return spy[f].ch[1]==x; }
void connect(int x,int f,int s){ spy[f].ch[s]=x,spy[x].fa=f; }
void newnode(int &now,int fa,int val){ spy[now=++cnt]={{0,0},fa,val,1}; }
void rotate(int x){
int f=spy[x].fa, ff=spy[f].fa, k=ident(x,f);
connect(spy[x].ch[k^1],f,k), connect(x,ff,ident(f,ff)), connect(f,x,k^1);
update(f),update(x);
}
void splay(int x,int top){
if(!top)root=x;
while(spy[x].fa!=top){
int f=spy[x].fa,ff=spy[f].fa;
if(ff!=top) ident(f,ff)^ident(x,f)?rotate(x):rotate(f);
rotate(x);
}
}
void ins(int val,int &now=root,int fa=0){
if(!now) newnode(now,fa,val),splay(now,0);
else if(val<spy[now].val) ins(val,spy[now].ch[0],now);
else ins(val,spy[now].ch[1],now);
}
void delnode(int x){
splay(x,0);
if(spy[x].ch[1]){
int p=spy[x].ch[1];
while(spy[p].ch[0])p=spy[p].ch[0];
splay(p,x);
connect(spy[x].ch[0],p,0);
root=p, spy[p].fa=0;
update(root);
}
else root=spy[x].ch[0],spy[root].fa=0;
}
void del(int val,int now=root){
if(val==spy[now].val) delnode(now);
else if(val<spy[now].val) del(val,spy[now].ch[0]);
else del(val,spy[now].ch[1]);
}
int getrank(int val){
int now=root,rank=1,pre=0;
while(now){
//cout<<val<<" and "<<spy[now].val<<endl;
if(val<=spy[now].val) pre=now,now=spy[now].ch[0];
else rank+=spy[spy[now].ch[0]].siz+1,now=spy[now].ch[1];
}
if(pre) splay(pre,0);
return rank;
}
int getnum(int rank){
int now=root;
while(now){
if(spy[spy[now].ch[0]].siz+1==rank){
splay(now,0); break;
}
else if(spy[spy[now].ch[0]].siz>=rank)now=spy[now].ch[0];
else rank-=spy[spy[now].ch[0]].siz+1,now=spy[now].ch[1];
}
return spy[now].val;
}
//#define endl '\n'
signed main(){
//freopen("C:\\Users\\egoist\\Desktop\\in.txt","r",stdin);
//freopen("C:\\Users\\egoist\\Desktop\\out.txt","w",stdout);
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t; cin>>t;
while(t--){
int opt,x; cin>>opt>>x;
if(opt==1) ins(x);
if(opt==2) del(x);
if(opt==3) cout<<getrank(x)<<endl;
if(opt==4) cout<<getnum(x)<<endl;
if(opt==5) cout<<getnum(getrank(x)-1)<<endl;
if(opt==6) cout<<getnum(getrank(x+1))<<endl;
//
}
}
pbds(??? 6行就完事了?)
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;
#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))
const int mod = 1e9+7;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>rb;
#define endl '\n'
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int q; cin>>q;
for(int i=1;i<=q;i++){
int op,k; cin>>op>>k;
if(op==1) rb.insert((k<<20)+i);
if(op==2) rb.erase(rb.lower_bound(k<<20));
if(op==3) cout<<rb.order_of_key(k<<20)+1<<endl;;
if(op==4) cout<<((*rb.find_by_order(k-1))>>20)<<endl;
if(op==5) cout<<((*--rb.lower_bound(k<<20))>>20)<<endl;
if(op==6) cout<<((*rb.upper_bound((k<<20)+q))>>20)<<endl;
}
}