题意:传送门
Splay讲解参考传送门
题解:因为之后要每天绝对值差最小,所以可以在插入后看下是否此时根这个值的数量大于1,是跳过即可,不是那么找下此时这个树的前驱与后继,然后加上最小的即可。
附上代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;
inline int read()
{
register int x=0,t=1;
register char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-'){t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*t;
}
int root,tot;
struct Node
{
int ch[2];
int val;
int ff;
int size;
int cnt;
}t[maxn];
inline void pushup(int u)
{
t[u].size=t[t[u].ch[0]].size+t[t[u].ch[1]].size+t[u].cnt;
}
inline void rotate(int x)
{
int y=t[x].ff;
int z=t[y].ff;
int k=(t[y].ch[1]==x);
t[z].ch[t[z].ch[1]==y]=x;
t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];
t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;
t[y].ff=x;
pushup(y);pushup(x);
}
inline void splay(int x,int goal)
{
while(t[x].ff!=goal){
int y=t[x].ff;
int z=t[y].ff;
if(z!=goal){
(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
}
rotate(x);
}
if(goal==0){
root=x;
}
}
inline void insert(int x)
{
int u=root,ff=0;
while(u&&t[u].val!=x){
ff=u;
u=t[u].ch[x>t[u].val];
}
if(u){
t[u].cnt++;
}else{
u=++tot;
if(ff){
t[ff].ch[x>t[ff].val]=u;
}
t[u].ch[0]=t[u].ch[1]=0;
t[tot].ff=ff;
t[tot].val=x;
t[tot].cnt=1;
t[tot].size=1;
}
splay(u,0);
}
inline void find(int x)
{
int u=root;
if(!u){
return;
}
while(t[u].ch[x>t[u].val]&&x!=t[u].val){
u=t[u].ch[x>t[u].val];
}
splay(u,0);
}
inline int Next(int x,int f)
{
find(x);
int u=root;
if(t[u].val>x&&f){
return u;
}
if(t[u].val<x&&!f){
return u;
}
u=t[u].ch[f];
while(t[u].ch[f^1]){
u=t[u].ch[f^1];
}
return u;
}
inline void Delete(int x)
{
int last=Next(x,0);
int next=Next(x,1);
splay(last,0);splay(next,last);
int del=t[next].ch[0];
if(t[del].cnt>1){
t[del].cnt--;
splay(del,0);
}else{
t[next].ch[0]=0;
}
}
inline int kth(int x)
{
int u=root;
if(t[u].size<x){
return 0;
}
while(1){
int y=t[u].ch[0];
if(x>t[y].size+t[u].cnt){
x-=t[y].size+t[u].cnt;
u=t[u].ch[1];
}else{
if(t[y].size>=x){
u=y;
}else{
return t[u].val;
}
}
}
}
int main()
{
int n=read();
insert(-214748647);
insert(+214748647);
int ans;
scanf("%d",&ans);
insert(ans);
for(int i=2;i<=n;i++){
int x=read();
insert(x);
if(t[root].cnt>1){
continue;
}else{
int a1=t[Next(x,0)].val;
int a2=t[Next(x,1)].val;
ans+=min(abs(x-a1),abs(x-a2));
}
}
printf("%d\n",ans);
return 0;
}
还可以先查找这个数的前驱和后继,不过要将板子>与<都要改为>=与<=,然后写就可以了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;
inline int read()
{
register int x=0,t=1;
register char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-'){t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*t;
}
int root,tot;
struct Node
{
int ch[2];
int val;
int ff;
int size;
int cnt;
}t[maxn];
inline void pushup(int u)
{
t[u].size=t[t[u].ch[0]].size+t[t[u].ch[1]].size+t[u].cnt;
}
inline void rotate(int x)
{
int y=t[x].ff;
int z=t[y].ff;
int k=(t[y].ch[1]==x);
t[z].ch[t[z].ch[1]==y]=x;
t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];
t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;
t[y].ff=x;
pushup(y);pushup(x);
}
inline void splay(int x,int goal)
{
while(t[x].ff!=goal){
int y=t[x].ff;
int z=t[y].ff;
if(z!=goal){
(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
}
rotate(x);
}
if(goal==0){
root=x;
}
}
inline void insert(int x)
{
int u=root,ff=0;
while(u&&t[u].val!=x){
ff=u;
u=t[u].ch[x>t[u].val];
}
if(u){
t[u].cnt++;
}else{
u=++tot;
if(ff){
t[ff].ch[x>t[ff].val]=u;
}
t[u].ch[0]=t[u].ch[1]=0;
t[tot].ff=ff;
t[tot].val=x;
t[tot].cnt=1;
t[tot].size=1;
}
splay(u,0);
}
inline void find(int x)
{
int u=root;
if(!u){
return;
}
while(t[u].ch[x>t[u].val]&&x!=t[u].val){
u=t[u].ch[x>t[u].val];
}
splay(u,0);
}
inline int Next(int x,int f)
{
find(x);
int u=root;
if(t[u].val>=x&&f){
return u;
}
if(t[u].val<=x&&!f){
return u;
}
u=t[u].ch[f];
while(t[u].ch[f^1]){
u=t[u].ch[f^1];
}
return u;
}
inline void Delete(int x)
{
int last=Next(x,0);
int next=Next(x,1);
splay(last,0);splay(next,last);
int del=t[next].ch[0];
if(t[del].cnt>1){
t[del].cnt--;
splay(del,0);
}else{
t[next].ch[0]=0;
}
}
inline int kth(int x)
{
int u=root;
if(t[u].size<x){
return 0;
}
while(1){
int y=t[u].ch[0];
if(x>t[y].size+t[u].cnt){
x-=t[y].size+t[u].cnt;
u=t[u].ch[1];
}else{
if(t[y].size>=x){
u=y;
}else{
return t[u].val;
}
}
}
}
int main()
{
int n=read();
insert(-214748647);
insert(+214748647);
int ans;
scanf("%d",&ans);
insert(ans);
for(int i=2;i<=n;i++){
int x=read();
int a1=t[Next(x,0)].val;
int a2=t[Next(x,1)].val;
ans+=min(abs(x-a1),abs(x-a2));
insert(x);
}
printf("%d\n",ans);
return 0;
}