bzoj1588 [HNOI2002]营业额统计

来源:互联网 发布:职业经理人 知乎 编辑:程序博客网 时间:2024/05/21 01:27

题目

平衡树的简单应用。
求前驱和后继,插入,可以说是十分简单的。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<cmath>#define MAXN 100000using namespace std;struct tree{    long long lc;    long long rc;    long long val;    long long num;    long long fa;};tree T[MAXN+1];long long rt,size,n,x;long long A[MAXN+1];void zig(long long x){    long long y=T[x].fa;    T[y].lc=T[x].rc;    if(T[x].rc!=-1)        T[T[x].rc].fa=y;    T[x].fa=T[y].fa;    if(T[y].fa!=-1)    {        if(T[T[y].fa].lc==y)T[T[y].fa].lc=x;        else T[T[y].fa].rc=x;    }    T[y].fa=x;    T[x].rc=y;}void zag(long long x){    long long y=T[x].fa;    T[y].rc=T[x].lc;    if(T[x].lc!=-1)        T[T[x].lc].fa=y;    T[x].fa=T[y].fa;    if(T[y].fa!=-1)    {        if(T[T[y].fa].lc==y)T[T[y].fa].lc=x;        else T[T[y].fa].rc=x;    }    T[y].fa=x;    T[x].lc=y;}long long splay(long long x,long long &rt){    while(T[x].fa!=-1)    {        long long y=T[x].fa;        if(T[y].fa==-1)        {            if(x==T[y].lc)zig(x);            else zag(x);            break;        }        if(x==T[y].lc)        {            if(y==T[T[y].fa].lc)                zig(y),zig(x);                    else                        zig(x),zag(x);        }        else        {            if(y==T[T[y].fa].rc)                zag(y),zag(x);                    else                        zag(x),zig(x);        }    }    rt=x;}void insert(long long x){    long long pos=rt;    long long k;    if(size==0)    {        rt=1;        size++;        T[1].val=x;        T[1].num=1;        T[1].fa=-1;        T[1].lc=T[1].rc=-1;        return;    }    while(true)    {        k=pos;        if(x==T[k].val){            T[k].num++;            return;        }        if(x<T[k].val)k=T[k].lc;        else k=T[k].rc;        if(k==-1)        {            if(x<T[pos].val)T[pos].lc=++size;            else T[pos].rc=++size;            T[size].val=x;            T[size].num=1;            T[size].lc=T[size].rc=-1;            T[size].fa=pos;            splay(size,rt);            return;        }        pos=k;    }}long long find(long long x){    long long pos=rt;    while(pos!=-1)    {        if(T[pos].val==x)return pos;        if(T[pos].val<x)pos=T[pos].rc;        else pos=T[pos].lc;    }    return 0;}long long MAXi(long long x){    long long pos=x;    while(T[pos].rc!=-1)pos=T[pos].rc;    return T[pos].val;}long long MINi(long long x){    long long pos=x;    while(T[pos].lc!=-1)pos=T[pos].lc;    return T[pos].val;}long long pre(long long x){    long long k=find(x);    if(k)    {        splay(k,rt);        if(T[rt].num>=2)return x;        if(T[rt].lc==-1)return -1;        return MAXi(T[rt].lc);    }}long long suf(long long x){    long long k=find(x);    if(k)    {        splay(k,rt);        if(T[rt].num>=2)return x;        if(T[rt].rc==-1)return -1;        return MINi(T[rt].rc);    }}void write(long long x){    if(T[x].lc!=-1)write(T[x].lc);    for(long long i=1;i<=T[x].num;i++)        cout<<T[x].val<<" ";    if(T[x].rc!=-1)write(T[x].rc);}long long ans;long long MIN;long long SUF,PRE;int main(){    scanf("%lld",&n);    ans=0;    scanf("%lld",&x);insert(x);    ans=x;    for(long long i=2;i<=n;i++)    {        scanf("%lld",&x);        insert(x);        MIN=100000000000;        SUF=suf(x);        if(SUF!=-1)MIN=min(MIN,abs(SUF-x));        PRE=pre(x);        if(PRE!=-1)MIN=min(MIN,abs(PRE-x));        ans+=MIN;    }    cout<<ans;    return 0;}

版子写得丑233

原创粉丝点击