想试下新找的板子,没想到交上去CE了。。懒得调。。以后有机会就改

/*
用type标记当前树上的是宠物还是人
每次求前驱后缀,删掉最近的那个点
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define maxn 1000100
#define L ch[r][0]
#define R ch[r][1]
#define KT ch[ch[r][1]][0] struct Splay{
int pre[maxn],sz[maxn],ch[maxn][],val[maxn],rt,tot;
int flag;
inline void newnode(int &r,int fa,int key){
r=++tot;
L=R=;
pre[r]=fa;
val[r]=key;
sz[r]=;
sz[L]=sz[R]=;
}
inline void pushup(int r){
sz[r]=;
if(L) sz[r]+=sz[L];
if(R) sz[r]+=sz[R];
}
inline void init(){//加两个边界
rt=tot=flag=;
ch[rt][]=ch[rt][]=sz[rt]=pre[rt]=;
newnode(rt,,-);
newnode(ch[rt][],rt,);
memset(sz,,sizeof sz);
}
inline void rotate(int x,int f) {
int y=pre[x];
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[pre[y]][] == y ] =x;
ch[x][f] = y;
pre[y] = x;
pushup(y);
}
inline void splay(int x,int goal) { //将x旋转到goal的下面
while(pre[x] != goal) {
if(pre[pre[x]] == goal) rotate(x , ch[pre[x]][] == x);
else {
int y=pre[x],z=pre[y];
int f = (ch[z][]==y);
if(ch[y][f] == x) rotate(x,!f),rotate(x,f);
else rotate(y,f),rotate(x,f);
}
}
pushup(x);
if(goal==) rt=x;
} inline void insert(int &r,int key,int fa){
if(!r){newnode(r,fa,key);splay(r,);return;}
else if(key<val[r]) insert(L,key,r);
else insert(R,key,r);
pushup(r);
}
inline int findkth(int r,int k){//找第k大的那个结点的值
if(k==sz[L]+) {splay(r,);return val[r];}
else if(k<sz[L]+)
return findkth(L,k);
else return findkth(R,k-sz[L]-);
}
inline int find(int r,int key){//找键值为key的结点
if(!r) return ;//不存在这个键值
else if(key==val[r]) return r;
else if(key<val[r]) find(L,key);
else find(R,key);
}
void remove(){
int t=rt;
if(ch[rt][]){//删掉根节点并以后缀作为根
rt=ch[rt][];
splay(getmin(rt),);
ch[rt][]=ch[t][];
if(ch[rt][]) pre[ch[rt][]]=rt;
}
else rt=ch[rt][];
pre[rt]=;
pushup(rt);
}
void findpre(int r,int key,int &ans){//找前驱结点(找值比key小的的最大的结点)
if(!r) return;
if(key>=val[r]) {ans=r;findpre(R,key,ans);}
else findpre(L,key,ans);
}
void findsucc(int r,int key,int &ans){///找后继
if(!r) return;
if(key<=val[r]) {ans=r;findsucc(L,key,ans);}
else findsucc(R,key,ans);
}
inline int getmin(int r){while(L) r=L;return r;}
inline int getmax(int r){while(R) r=R;return r;} inline void vist(int r){
if(r){
printf("结点%2d : 左儿子 %2d 右儿子 %2d val:%2d sz=%d\n",r,L,R,val[r],sz[r]);
vist(L);
vist(R);
}
}
void debug() {
puts("");
vist(rt);
puts("");
}
}spt;
int main(){
int n,a,b,ans;
while(scanf("%d",&n)==){
spt.init();
ans=;
for(int i=;i<=n;i++){
scanf("%d%d",&a,&b);
// spt.debug();
if(spt.sz[spt.rt]==){
spt.flag=a;
spt.insert(spt.rt,b,);
}
else {
if(spt.flag==a) spt.insert(spt.rt,b,);
else {
int tmp1,tmp2;
spt.findpre(spt.rt,b,tmp1);
spt.findsucc(spt.rt,b,tmp2);
if(abs(b-spt.val[tmp1])<=abs(b-spt.val[tmp2])){
ans+=abs(b-spt.val[tmp1]);
spt.splay(tmp1,);
spt.remove();
}
else {
ans+=abs(b-spt.val[tmp2]);
spt.splay(tmp2,);
spt.remove();
}
}
}
// spt.debug();
}
printf("%d\n",ans);
}
return ;
}
04-19 12:39