模板题,就不说了,相信做了前面几道题就会这个了。。。就找一找前驱和后继嘛。。。。
注意一个点:这里一个数的“前驱”和“后继”应包括那个数本身。[因为数据中有重复的数,我用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 "); if(T == Null) { // printf("sfd %d ",T -> data); return -INF;} // printf("dfas %d %d %d ",T -> data,ball,T -> son[0] -> data); if(T -> data > ball) return Precursor (T -> son[0]); // printf("dsl "); 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 ",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 ",ans); return 0; }
That is all. Thank you for watching.