BZOJ 1588 Treap模版題
阿新 • • 發佈:2019-01-28
題意:中文題,但是注意輸入有點問題,可以看看討論,大神們的測試出來的
思路:我的是用Treap找到當前值的排名k,然後找k+1和k-1的值與當前值的絕對值之差的最小值,加起來最後輸出即可
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=100010; struct treap_node{ treap_node *left,*right; int val,fix,wgt,size; treap_node(int val): val(val) {left=right=NULL; size=wgt=1; fix=rand(); } int lsize(){ if (left) return left->size; else return 0; } int rsize(){ if (right) return right->size; else return 0; } void Maintain(){ size=wgt; size+=lsize()+rsize(); } }; treap_node *root; int n,minn,size,i; void tlr(treap_node *&a){ treap_node *b=a->right; a->right=b->left; b->left=a; a->Maintain(); b->Maintain(); a=b; } void trr(treap_node *&a){ treap_node *b=a->left; a->left=b->right; b->right=a; a->Maintain(); b->Maintain(); a=b; } void treap_insert(treap_node *&p,int value){ if (!p) p=new treap_node(value); else{ if (value==p->val) p->wgt++; if (value<p->val){ treap_insert(p->left,value); if (p->left->fix<p->fix) trr(p); } if (value>p->val){ treap_insert(p->right,value); if (p->right->fix<p->fix) tlr(p); } } p->Maintain(); } void del(treap_node *&p,int d){ if (p->val==d){ if (p->wgt==1){ if (!p->left||!p->right){ if (!p->left) p=p->right; else p=p->left; } else{ if (p->left->fix<p->right->fix){ trr(p); del(p->right,d); } else{ tlr(p); del(p->left,d); } } } else p->wgt--; } else{ if (d<p->val) del(p->left,d); if (d>p->val) del(p->right,d); } if (p!=NULL) p->Maintain(); } int treap_rank(treap_node *p,int value,int cnt){ int t=p->lsize(); if(value==p->val) return t+cnt+1; else if(value<p->val) return treap_rank(p->left,value,cnt); else return treap_rank(p->right,value,t+cnt+p->wgt); } treap_node *Treap_kth(treap_node *&p,int k){ if (k<p->lsize()+1) return Treap_kth(p->left,k); else if (k>p->lsize()+p->wgt) return Treap_kth(p->right,k-p->lsize()-p->wgt); else return p; } int main(){ int n,a,b,c; scanf("%d",&n); int ans=0; for(int i=0;i<n;i++){ if(scanf("%d",&a)==EOF) a=0; treap_insert(root,a); if(i==0){ ans+=a;continue; } int k=treap_rank(root,a,0);; treap_node *t1=NULL,*t2=NULL; if(k!=1) t1=Treap_kth(root,k-1); if(k!=i+1) t2=Treap_kth(root,k+1); if(!t1) ans+=abs(t2->val-a); else if(!t2) ans+=abs(t1->val-a); else ans+=min(abs(t1->val-a),abs(t2->val-a)); } printf("%d\n",ans); return 0; }