这一道题,出题就为了强行掩饰这是一道裸的平衡树硬生生装题面。裸的平衡树,找前缀后缀就可以了,但是数据太水了,我的手撕splay居然和stl的set速度只是快了一点,我不服
#include<cstring>
#include<iostream>
#define Mod 1000000
#include<set>
using namespace std;
int n,pos,ans;
set<int>s;
void query(int x){
set<int>::iterator l,r;
l=--s.lower_bound(x),r=s.lower_bound(x);
if(x-(*l)<=(*r)-x&&*l!=-1e9)ans=(ans+x-(*l))%Mod,s.erase(l);
else ans=(ans+(*r)-x)%Mod,s.erase(r);
}
int main(){
s.insert(-1e9),s.insert(1e9);
scanf("%d",&n);
int a,b;
while(n--){
scanf("%d%d",&a,&b);
if(s.size()==2){
s.insert(b),pos=a;
}else if(a==pos)s.insert(b);
else query(b);
}
printf("%d",ans);
return 0;
}
splay(一开始把找前缀和后缀写错了心累)
#include<cstdio>
#include<cstring>
#include<iostream>
#define Mod 1000000
#define LL long long
using namespace std;
int n,ans;
struct Tree{
Tree *ch[2],*f;
int w;
Tree(Tree* a,Tree* b,Tree* c,int x){
w=x;ch[0]=a,ch[1]=b,f=c;
}
};
Tree *rt=NULL;
void rotate(Tree* u){
if(u->f==NULL)return;
Tree* f=u->f,*ff=f->f;
int d= u == f->ch[0];
f->ch[!d]=u->ch[d];
if(u->ch[d]!=NULL)u->ch[d]->f=f;
u->ch[d]=f;
f->f=u;
u->f=ff;
if(ff!=NULL)ff->ch[f==ff->ch[1]]=u;
}
void splay(Tree* u,Tree* top=NULL){
while(u->f!=top){
Tree* f=u->f,*ff=f->f;
if(ff==top){
rotate(u);break;
}
int d= u==f->ch[1], dd= f==ff->ch[1];
if(d==dd)rotate(f);
else rotate(u);
rotate(u);
}
rt=u;
}
int t1,t2;
void query_front(Tree* u,int x){
if(u->w >x){
if(u->ch[0]!=NULL)query_front(u->ch[0],x);
}else{
t1=u->w;//一开始忘了
if(u->ch[1]!=NULL)query_front(u->ch[1],x);
}
}
void query_behin(Tree* u,int x){
if(u->w < x){
if(u->ch[1]!=NULL)query_behin(u->ch[1],x);
}else{
t2=u->w;
if(u->ch[0]!=NULL)query_behin(u->ch[0],x);
}
}
void insert(Tree* u,int x){
if(rt==NULL){
rt=new Tree(NULL,NULL,NULL,x);
return;
}
if(x> u->w){
if(u->ch[1]!=NULL)insert(u->ch[1],x);
else {
u->ch[1]=new Tree(NULL,NULL,u,x);
splay(u->ch[1]);
}
}else{
if(u->ch[0]!=NULL)insert(u->ch[0],x);
else{
u->ch[0]=new Tree(NULL,NULL,u,x);
splay(u->ch[0]);
}
}
}
Tree* find(Tree* u){
if(u->ch[1]!=NULL)return find(u->ch[1]);
return u;
}
void del(Tree* u,int x){
if(u->w==x){
splay(u);
Tree* x=find(u->ch[0]);
splay(x,u);
Tree* ls=u->ch[0],*rs=u->ch[1];
rt=ls;
rs->f =ls,ls->f=NULL;
ls->ch[1]=rs;
}else if(u->w > x){
del(u->ch[0],x);
}else del(u->ch[1],x);
}
void query(int x){
int l,r,d,dd;t1=-1e9,t2=1e9;
query_front(rt,x);l=t1;
query_behin(rt,x);r=t2;
if(l!=-1e9&&x-l<=r-x){
ans=(ans+x-l)%Mod;
del(rt,l);
}else if(r!=1e9){
ans=(r-x+ans)%Mod;
del(rt,r);
}
}
int main(){
int pos,last=0,a,b;
insert(rt,1e9),insert(rt,-1e9);
scanf("%d",&n);
while(n--){
scanf("%d%d",&a,&b);
if(last==0){
pos=a;insert(rt,b);last=1;
}else if(a==pos)insert(rt,b),last++;
else query(b),last--;
}
printf("%d",ans);
return 0;
}
续了一个内存池,可是也没快多少(数据一大就有用了):
#include<cstdio>
#include<cstring>
#include<iostream>
#define Mod 1000000
#define LL long long
using namespace std;
int n,ans,cnt;
struct Tree{
Tree *ch[2],*f;
int w;
Tree(Tree* a=NULL,Tree* b=NULL,Tree* c=NULL,int x=0){
w=x;ch[0]=a,ch[1]=b,f=c;
}
}cur[100200];
Tree *rt=NULL;
void rotate(Tree* u){
if(u->f==NULL)return;
Tree* f=u->f,*ff=f->f;
int d= u == f->ch[0];
f->ch[!d]=u->ch[d];
if(u->ch[d]!=NULL)u->ch[d]->f=f;
u->ch[d]=f;
f->f=u;
u->f=ff;
if(ff!=NULL)ff->ch[f==ff->ch[1]]=u;
}
void splay(Tree* u,Tree* top=NULL){
while(u->f!=top){
Tree* f=u->f,*ff=f->f;
if(ff==top){
rotate(u);break;
}
int d= u==f->ch[1], dd= f==ff->ch[1];
if(d==dd)rotate(f);
else rotate(u);
rotate(u);
}
rt=u;
}
int t1,t2;
void query_front(Tree* u,int x){
if(u->w >x){
if(u->ch[0]!=NULL)query_front(u->ch[0],x);
}else{
t1=u->w;//一开始忘了
if(u->ch[1]!=NULL)query_front(u->ch[1],x);
}
}
void query_behin(Tree* u,int x){
if(u->w < x){
if(u->ch[1]!=NULL)query_behin(u->ch[1],x);
}else{
t2=u->w;
if(u->ch[0]!=NULL)query_behin(u->ch[0],x);
}
}
void insert(Tree* u,int x){
if(rt==NULL){
cur[++cnt]=Tree(NULL,NULL,NULL,x);
rt=&cur[cnt];
return;
}
if(x> u->w){
if(u->ch[1]!=NULL)insert(u->ch[1],x);
else {
cur[++cnt]=Tree(NULL,NULL,u,x);
u->ch[1]=&cur[cnt];
splay(u->ch[1]);
}
}else{
if(u->ch[0]!=NULL)insert(u->ch[0],x);
else{
cur[++cnt]=Tree(NULL,NULL,u,x);
u->ch[0]=&cur[cnt];
splay(u->ch[0]);
}
}
}
Tree* find(Tree* u){
if(u->ch[1]!=NULL)return find(u->ch[1]);
return u;
}
void del(Tree* u,int x){
if(u->w==x){
splay(u);
Tree* x=find(u->ch[0]);
splay(x,u);//注意,删除的时候必须要先把前面的提起来
Tree* ls=u->ch[0],*rs=u->ch[1];
rt=ls;
rs->f =ls,ls->f=NULL;
ls->ch[1]=rs;
}else if(u->w > x){
del(u->ch[0],x);
}else del(u->ch[1],x);
}
void query(int x){
int l,r,d,dd;t1=-1e9,t2=1e9;
query_front(rt,x);l=t1;
query_behin(rt,x);r=t2;
if(l!=-1e9&&x-l<=r-x){
ans=(ans+x-l)%Mod;
del(rt,l);
}else if(r!=1e9){
ans=(r-x+ans)%Mod;
del(rt,r);
}
}
int main(){
int pos,last=0,a,b;
insert(rt,1e9),insert(rt,-1e9);
scanf("%d",&n);
while(n--){
scanf("%d%d",&a,&b);
if(last==0){
pos=a;insert(rt,b);last=1;
}else if(a==pos)insert(rt,b),last++;
else query(b),last--;
}
printf("%d",ans);
return 0;
}