https://www.lydsy.com/JudgeOnline/problem.php?id=1588
treap模板题
边读入,边求每个数的前驱和后继
上代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std;
struct Treap{
int l,r;
int cnt,dat;
int val,siz;
}a[32800];
int n,root,tot,INF=2147483647,ans=0,b[32800];
int New(int val) {
a[++tot].val=val;
a[tot].cnt=a[tot].siz=1;
a[tot].dat=rand();
return tot;
}
void Update(int p) {
a[p].siz=a[a[p].l].siz+a[a[p].r].siz+a[p].cnt;
}
void Build() {
New(-INF); New(INF);
root=1; a[1].r=2;
Update(root);
}
void Zig(int &p) {
int q=a[p].l;
a[p].l=a[q].r; a[q].r=p; p=q;
Update(a[p].r); Update(p);
}
void Zag(int &p) {
int q=a[p].r;
a[p].r=a[q].l; a[q].l=p; p=q;
Update(a[p].l); Update(p);
}
void Insert(int &p,int val) {
if(p==0) {
p=New(val);
return;
}
if(val==a[p].val) {
a[p].cnt++;
Update(p);
return;
}
if(val<a[p].val) {
Insert(a[p].l,val);
if(a[p].dat<a[a[p].l].dat) Zig(p);
}
else {
Insert(a[p].r,val);
if(a[p].dat<a[a[p].r].dat) Zag(p);
}
Update(p);
}
int Getpre(int val) {
int p=root,ans=1;
while(p) {
if(val==a[p].val) {
if(a[p].l>0) {
p=a[p].l;
while(a[p].r>0) p=a[p].r;
ans=p;
}
break;
}
if(a[p].val<val && a[p].val>a[ans].val) ans=p;
p = val < a[p].val ? a[p].l : a[p].r;
}
return a[ans].val;
}
int Getnext(int val) {
int p=root,ans=2;
while(p) {
if(val==a[p].val) {
if(a[p].r>0) {
p=a[p].r;
while(a[p].l>0) p=a[p].l;
ans=p;
}
break;
}
if(a[p].val>val && a[p].val<a[ans].val) ans=p;
p = val < a[p].val ? a[p].l : a[p].r;
}
return a[ans].val;
}
int Get(int p,int val) {
if(p==0) return 0;
if(val==a[p].val) return p;
return val < a[p].val ? Get(a[p].l,val) : Get(a[p].r,val);
}
int main()
{
Build();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
Insert(root,b[i]);
if(i==1) {ans+=b[i];continue;}
if(a[Get(root,b[i])].cnt>1) continue;
int u=Getpre(b[i]),v=Getnext(b[i]);
if(u==-2147483647) u=-u;
ans+=min(abs(b[i]-u),abs(b[i]-v));
}
printf("%d",ans);
return 0;
}