洛谷题目:https://www.luogu.org/problem/show?pid=2234
set解法:http://blog.youkuaiyun.com/sdfzsyh/article/details/72790622
没错还是P2234
所以说我有多么爱这道题~~
当然这道很模板的题非常好~~
所以这道题对于自平衡搜索树初学者还是非常好的!
说白了,就是一道求前驱后继的题;
但是有一些点需要注意:
1、开始的时候插入极大值和极小值作为边界,否则会WA;
2、插入及旋转的取地址符千万不要忘。
还是贴代码吧=.=:
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int inf=0x3f3f3f3f;
int a,n,sub,pro,tot,root,answer;
struct Treap
{
int val;
int pro;
int num;
int lch,rch;
int ln,rn;
} treap[32800];
inline void turn_right(int &p)
{
int t=treap[p].lch;
treap[p].lch=treap[t].rch;
treap[t].rch=p;
p=t;
}
inline void turn_left(int &p)
{
int t=treap[p].rch;
treap[p].rch=treap[t].lch;
treap[t].lch=p;
p=t;
}
void treap_insert(int &p,int x)
{
if(p==0)
{
tot++;p=tot;
treap[p].pro=rand();
treap[p].val=x;
return ;
}
if(treap[p].val<x)
{
treap_insert(treap[p].rch,x);
if(treap[p].pro<treap[treap[p].rch].pro)turn_left(p);
}
else
{
treap_insert(treap[p].lch,x);
if(treap[p].pro<treap[treap[p].lch].pro)turn_right(p);
}
}
inline void qsub(int k,int x)
{
if (!k) return;
if (treap[k].val<=x)
{
sub=treap[k].val;
qsub(treap[k].rch,x);
}
else qsub(treap[k].lch,x);
}
inline void qpro(int k,int x)
{
if (!k) return;
if (treap[k].val>=x)
{
pro=treap[k].val;
qpro(treap[k].lch,x);
}
else qpro(treap[k].rch,x);
}
int main()
{
root=0;
scanf("%d",&n);
scanf("%d",&a);
treap_insert(root,inf);
treap_insert(root,-inf);
treap_insert(root,a);
answer=a;
for(int i=2;i<=n;i++)
{
scanf("%d",&a);
qpro(root,a);
qsub(root,a);
answer+=min(abs(a-sub),abs(a-pro));
treap_insert(root,a);
}
printf("%d",answer);
}