a2lyaXNhbWUgbWFyaXNh @ 2023-01-13 09:53:46
传统有旋 Treap,普通版过了,52 不是 TLE 而是 WA
#include <bits/stdc++.h>
using namespace std;
#define INF 0x7f7f7f7f
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
uniform_int_distribution<> dis(0,INF);
struct TREAP{
int val,pri;
int cnt,size;
int l,r;
}t[2000020];
int cur,root,n,m,last,ansxor;
inline int NEW(int v){
t[++cur].val=v;
t[cur].pri=dis(rnd);
t[cur].cnt=t[cur].size=1;
return cur;
}//新节点
inline void PUSHUP(int k){
t[k].size=t[t[k].l].size+t[t[k].r].size+t[k].cnt;
}//更新子树大小
inline void BUILD(){
NEW(-INF),NEW(INF);
root=1;
t[root].r=2;
PUSHUP(root);
}//建树
inline int GETRNK(int x,int k){
if(k==0)return 0;
if(x==t[k].val)return t[t[k].l].size+1;
if(x<t[k].val)return GETRNK(x,t[k].l);
if(x>t[k].val)return t[t[k].l].size+t[k].cnt+GETRNK(x,t[k].r);
}//获取排名
inline int GETVAL(int x,int k){
if(k==0)return INF;
if(t[t[k].l].size>=x)return GETVAL(x,t[k].l);
if(t[t[k].l].size+t[k].cnt>=x)return t[k].val;
return GETVAL(x-t[t[k].l].size-t[k].cnt,t[k].r);
}//获取值
inline void ZIG(int &k){
int p=t[k].l;
t[k].l=t[p].r,t[p].r=k,k=p;
PUSHUP(t[k].r);PUSHUP(k);
}//左旋
inline void ZAG(int &k){
int p=t[k].r;
t[k].r=t[p].l,t[p].l=k,k=p;
PUSHUP(t[k].l);PUSHUP(k);
}//右旋
inline void INSERT(int v,int &k){
if(k==0){
k=NEW(v);
return;
}
if(v==t[k].val){
t[k].cnt++;
PUSHUP(k);
return;
}
if(v<t[k].val){
INSERT(v,t[k].l);
if(t[k].pri<t[t[k].l].pri)
ZIG(k);
}else{
INSERT(v,t[k].r);
if(t[k].pri<t[t[k].r].pri)
ZAG(k);
}
PUSHUP(k);
}//插入
int GETPRE(int v){
int ans=1;
int k=root;
while(k){
if(v==t[k].val){
if(t[k].l){
k=t[k].l;
while(t[k].r)
k=t[k].r;
ans=k;
}
break;
}
if(t[k].val<v&&t[k].val>t[ans].val)
ans=k;
k=v<t[k].val?t[k].l:t[k].r;
}
return t[ans].val;
}//获取前驱
int GETNXT(int v){
int ans=2;
int k=root;
while(k){
if(v==t[k].val){
if(t[k].r){
k=t[k].r;
while(t[k].l)
k=t[k].l;
ans=k;
}
break;
}
if(t[k].val>v&&t[k].val<t[ans].val)
ans=k;
k=v<t[k].val?t[k].l:t[k].r;
}
return t[ans].val;
}//获取后继
inline void DELETE(int v,int &k){
if(k==0)return;
if(v==t[k].val){
if(t[k].cnt>1){
t[k].cnt--;
PUSHUP(k);
return;
}
if(t[k].l||t[k].r){
if(t[k].r==0||t[t[k].l].pri>t[t[k].r].pri)
ZIG(k),DELETE(v,t[k].r);
else
ZAG(k),DELETE(v,t[k].l);
PUSHUP(k);
}else k=0;
return;
}
v<t[k].val?DELETE(v,t[k].l):DELETE(v,t[k].r);
PUSHUP(k);
}//删除
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(nullptr);
BUILD();
cin>>n>>m;
for(int i=1;i<=n;++i){
int tmp;
cin>>tmp;
INSERT(tmp,root);
}
while(m--){
int o,x;
cin>>o>>x;
x^=last;
switch(o){
case 1:
INSERT(x,root);
break;
case 2:
DELETE(x,root);
break;
case 3:
last=GETRNK(x,root)-1;
ansxor^=last;
break;
case 4:
last=GETVAL(x+1,root);
ansxor^=last;
break;
case 5:
last=GETPRE(x);
ansxor^=last;
break;
case 6:
last=GETNXT(x);
ansxor^=last;
break;
}
}
cout<<ansxor;
return 0;
}
lz 可能被 whk 作业薄杀了可能回复不及时
by a2lyaXNhbWUgbWFyaXNh @ 2023-01-13 09:54:23
调用系统函数不要管那是我调用了一个时间函数作为随机数种子
by AKPC @ 2023-01-13 10:02:33
c不会,在写线段树
by ROBOTGear @ 2023-01-13 14:41:34
经典错误,本题case3不保证x存在,所以查之前Insert一下,查完之后Del就好了
顺带一提你把左旋和右旋概念搞反了(虽然没影响)
by ROBOTGear @ 2023-01-13 14:51:22
还有些小问题,比如build那里面你没法保证-inf的pri大于inf的pri,以及你cur,ans,last,t[0].size,t[0].cnt一堆变量没初值,然后删除操作写复杂了,还有求前驱后继也写复杂了()