標籤:
左偏樹維護中位元。
低級錯誤:迴圈裡的變數
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n;struct Node{ int x,dis,size; Node *l,*r; void clear() { l=r=NULL; dis=0;size=1; }}a[50011];bool check_dis(Node *A){ if (A->r==NULL) return false; if (A->l==NULL) return true; return (A->r->dis>A->l->dis); }Node *merge(Node *A,Node *B){ if (A==NULL) return B; if (B==NULL) return A; if (A->x<B->x) swap(A,B); A->r=merge(A->r,B); if (check_dis(A)) swap(A->l,A->r); if (A->r==NULL) A->dis=0; else A->dis=A->r->dis+1; A->size=1; if (A->l!=NULL) A->size+=A->l->size; if (A->r!=NULL) A->size+=A->r->size; return A;}Node *Q[50011];int Qs[50011];int num=0;void fix(int i,int n){ //cout<<n<<"**"<<endl; //system("pause"); while (Q[i]->size>(n+1)/2) { //cout<<Q[i]->size<<endl; //system("pause"); Q[i]=merge(Q[i]->l,Q[i]->r); }}inline int abs(int x) {return x<0?(-x):x;}void init(){ for (int i=1;i<=n;i++) { a[i].clear(); scanf("%d",&a[i].x); } num=1;Q[1]=&a[1];Qs[0]=0;Qs[1]=1; for (int i=2;i<=n;i++) { num++; Q[num]=&a[i];Qs[num]=i; while (num>1&&Q[num]->x<Q[num-1]->x) { Q[num-1]=merge(Q[num],Q[num-1]); //cout<<num<<" "<<Qs[num]<<" "<<Qs[num-1]<<endl; Qs[num-1]=Qs[num];num--; //cout<<num<<"OO"<<endl; fix(num,Qs[num]-Qs[num-1]); //system("pause"); } } long long ans=0ll; for (int i=1;i<=num;i++) { for (int j=Qs[i-1]+1;j<=Qs[i];j++) { ans+=abs(a[j].x-Q[i]->x); } } //cout<<"*"<<num<<endl; //for (int i=1;i<=num;i++) // cout<<Qs[i]<<"*"<<(Q[i]->x)<<" "; //cout<<endl; printf("%lld\n",ans); }int main(){ while (scanf("%d",&n),n!=0) init(); return 0;}View Code
ZOJ Problem Set - 3512Financial Fraud