1. 程式人生 > >BZOJ1588_營業額統計_KEY

BZOJ1588_營業額統計_KEY

urn 可能 mes turn oid rand() 代碼 傳送門 space

題目傳送門

分析題意可得,希望求與每個數最相近的數。

二叉搜索樹的簡單題,因為可能被卡成O(N),考慮平衡樹。

因為Treap較簡單,此處用Treap編寫代碼。

code:

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

char tc()
{
    static char fl[10000000],*A=fl,*B=fl;
    return A==B&&(B=(A=fl)+fread(fl,1,10000000,stdin),A==B)?EOF:*A++;
}

int read() { char c;while(c=tc(),(c<0||c>9)&&c!=-);int x=0,y=1;c==-?y=-1:x=c-0; while(c=tc(),c>=0&&c<=9)x=x*10+c-0; return x*y; } int x,ans; int N,v[32768],tp[32768][2],r[32768],cnt,rt; int rotate(int &now,int x) { int k=tp[now][x]; tp[now][x]
=tp[k][x^1]; tp[k][x^1]=now; now=k; } int pre(int o,int x) { int res=2e9; while(o){ res=min(res,abs(v[o]-x)); o=tp[o][v[o]<x]; } return res; } void insert(int &now,int x) { if(!now){ now=++cnt; v[now]=x;r[now]=rand();
return ; } if(x==v[now])return ; int to=x>v[now]; insert(tp[now][to],x); if(r[now]<r[tp[now][to]])rotate(now,to); } main() { // freopen("x.txt","r",stdin); N=read(); for(int i=1;i<=N;i++){ x=read(); if(i==1)ans+=x; else ans+=pre(rt,x); insert(rt,x); } printf("%d",ans); return 0; }

BZOJ1588_營業額統計_KEY