RT 60pts TLE on #6 #7 #8 #9 #10
貌似是求krank的时候出错了 其中:
k-=tree[tree[u].son[0]].size+tree[u].cnt;
这一句话中的 tree[u].cnt 改成1后会WA,所以基本可以确定是这里出错了。
CODE:
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e6+10;
int n,root,cnt;
//save
struct poS/*potofSplay*/{
int son[2],fa,val;
int size,flag,cnt;
void init(int VAL,int FA){
val=VAL,fa=FA;
size=cnt=1;
}
}tree[N];
void update(int x){
tree[x].size=tree[tree[x].son[0]].size+tree[tree[x].son[1]].size+tree[x].cnt;
}void rotate(int x){
int y=tree[x].fa,z=tree[y].fa;
int lr=tree[y].son[1]==x;//0l 1r
tree[z].son[tree[z].son[1]==y]=x,tree[x].fa=z;
tree[y].son[lr]=tree[x].son[lr^1],tree[tree[x].son[lr^1]].fa=y;
tree[x].son[lr^1]=y,tree[y].fa=x;
update(y),update(x);
}void splay(int x,int k){
while(tree[x].fa!=k){
//cout<<1<<' ';
int y=tree[x].fa,z=tree[y].fa;
if(z!=k){
if((tree[z].son[1]==y)^(tree[y].son[1]==x)){
rotate(x);
}else{
rotate(y);
}
}rotate(x);
}if(!k) root=x;
}void ins(int v){
int u=root,fa=0;
while(u&&tree[u].val!=v){
fa=u,u=tree[u].son[v>tree[u].val];
}if(u){
tree[u].cnt++;
}else{
u=++cnt;
tree[u].cnt=1;
if(fa){
tree[fa].son[v>tree[fa].val]=u;
}tree[u].init(v,fa);
}splay(u,0);
}void Build(){
for(int i=0;i<=n+1;i++){
ins(i);
}
}int getrank(int v){
int u=root,ccnt=0;
while(true){
//cout<<u<<' '<<ccnt<<'\n';
if(v<tree[u].val){
u=tree[u].son[0];//find?yes
}else{
ccnt+=tree[tree[u].son[0]].size;
if(v==tree[u].val){
splay(u,0);
return ccnt+1;
}else{
ccnt+=tree[u].cnt;
u=tree[u].son[1];
}
}
}
}int getkrank(int k){
int u=root;
while(true){
if(tree[tree[u].son[0]].size>=k){
u=tree[u].son[0];
}else{
if(tree[tree[u].son[0]].size+1==k){
return tree[u].val;
}else{
k-=tree[tree[u].son[0]].size+tree[u].cnt;
u=tree[u].son[1];
}
}
}return -1;
}void Find(int x){
int u=root;
if(!u) return;
while(tree[u].son[x>tree[u].val]&&x!=tree[u].val){
u=tree[u].son[x>tree[u].val];
}splay(u,0);
}int PreSuc(int x,int f){
Find(x);
int u=root;
if((tree[u].val>x&&f)||(tree[u].val<x&&!f)) return u;
u=tree[u].son[f];
while(tree[u].son[f^1]) u=tree[u].son[f^1];
return u;
}void Delete(int x){
int last=PreSuc(x,0),next=PreSuc(x,1);
splay(last,0);splay(next,last);
int d=tree[next].son[0];
if(tree[d].cnt>1){
tree[d].cnt--;
splay(d,0);
}else{
tree[next].son[0]=0;
}
}signed main(){
ins(1e9);ins(-1e9);
cin>>n;
while(n--){
int opt,x;
cin>>opt>>x;
if(opt==1) ins(x);
if(opt==2) Delete(x);
if(opt==3) cout<<getrank(x)-1<<'\n';
if(opt==4) cout<<getkrank(x+1)<<'\n';
if(opt==5) cout<<tree[PreSuc(x,0)].val<<'\n';
if(opt==6) cout<<tree[PreSuc(x,1)].val<<'\n';
}
}