模板题,就不说了,相信做了前面几道题就会这个了。。。就找一找前驱和后继嘛。。。。
注意一个点:这里一个数的“前驱”和“后继”应包括那个数本身。[因为数据中有重复的数,我用bitset判重会re,不知是不是因为毒瘤数据。。。]
强上代码 :
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<bitset>
#define R121() ((rand() << 12) + (rand() << 7) + rand())
#define R233() (R121() % 45411445 + R121() % 4545128 + R121 () % 465187 + 1)
int ans;
const int N = 4e4 + 7,INF = 0x7fffffff;
class Treap {
private :
struct Node {
Node *son[2];
int size,num,data,hr;
Node () {}
Node (int data,Node *fl) : data(data) { son[0] = son[1] = fl; hr = R233(); size = num = 1; }
void update () { size = son[0] -> size + son[1] -> size + num; }
}*root,*pool,meme[N],*Null;
int ball;
void rotate (Node *&T,bool v) {
Node *Tt = T -> son[v];
T -> son[v] = Tt -> son[v^1];
Tt -> son[v^1] = T;
T -> update (); Tt -> update();
T = Tt;
}
void Insert (Node *&T) {
if(T == Null) { T = new (pool++) Node(ball,Null); return ; }
if(T -> data == ball) { ++ T -> size; ++ T -> num; return; }
bool v = T -> data < ball;
Insert (T -> son[v]);
if(T -> son[v] -> hr < T -> hr) rotate (T , v);
else T -> update();
}
int Subsequent (Node *&T) {
if(T == Null) return -INF;
if(T -> data < ball) return Subsequent (T -> son[1]);
int k = Subsequent (T -> son[0]);
return k == -INF ? T -> data : k;
}
int Precursor (Node *&T) {
// printf("ds\n");
if(T == Null) {
// printf("sfd %d\n",T -> data);
return -INF;}
// printf("dfas %d %d %d\n",T -> data,ball,T -> son[0] -> data);
if(T -> data > ball) return Precursor (T -> son[0]);
// printf("dsl\n");
int k = Precursor (T -> son[1]);
return k == -INF ? T -> data : k;
}
public :
Treap () { Null = new Node (); Null -> size = Null -> num = 0; }
void clear () { pool = meme; root = Null; }
void Ins (int xxx) { ball = xxx; Insert (root); }
int Sub (int xxx) { ball = xxx; return Subsequent (root); }
int Pre (int xxx) { ball = xxx; return Precursor (root); }
void Clc (int xxx) {
if(!root -> size) ans += xxx; else {
int a = Pre (xxx) , b = Sub (xxx);
// printf("f %d %d %d %d %d %d %d\n",xxx,r oot->size,root->data ,root->son[0]->data,a,b,root == Null);
if(a == -INF && b == -INF) return; //
else if(b == -INF) ans += xxx - a;
else if(a == -INF) ans += b - xxx;
else ans += std :: min (xxx - a,b - xxx);
}
Ins (xxx);
}
}treap;
int n,w;
int main () {
scanf("%d",&n); treap . clear();
for(int i=1;i<=n;++i) {
scanf("%d",&w); treap.Clc(w);
}
printf("%d\n",ans);
return 0;
}
That is all. Thank you for watching.