题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1588
简单Splay。但用双向链表做。很好的思路。
1.(离线)按值排序,记下pre和nxt的位置;2.倒序,为了算完把它删掉以不影响前面。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=32770,INF=1e7; int n,a[N],pre[N],nxt[N],ans; struct Node{ int val,bh; }tp[N]; bool cmp(Node a,Node b){return a.val<b.val;} int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]),tp[i].val=a[i],tp[i].bh=i; sort(tp+1,tp+n+1,cmp); for(int i=1;i<=n;i++)pre[tp[i].bh]=tp[i-1].bh,nxt[tp[i].bh]=tp[i+1].bh?tp[i+1].bh:n+1; a[n+1]=INF;a[0]=-INF; for(int i=n;i>1;i--) { ans+=min(a[i]-a[pre[i]],a[nxt[i]]-a[i]); pre[nxt[i]]=pre[i];nxt[pre[i]]=nxt[i]; } printf("%d",ans+a[1]); return 0; }