【BZOJ 1588】[HNOI2002] 营业额统计(Treap)

Description


营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。  输入输出要求

Input


第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i
天公司的营业额。
天数n<=32767,
每天的营业额ai <= 1,000,000。
最后结果T<=2^31

Output


输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。

Sample Input

6
5
1
2
5
4
6	

Sample Output

12

HINT


结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12

题解


百科treap

文库资料

使用treap维护这个序列,然后O(logn)查询左趋近x和右趋近x的值,从中选最小即可。

#include <queue>
#include <cstdio>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ll long long
#define inf 1000000000
#define PI acos(-1)
#define bug puts("here")
#define REP(i,x,n) for(int i=x;i<=n;i++)
#define DEP(i,n,x) for(int i=n;i>=x;i--)
#define mem(a,x) memset(a,x,sizeof(a))
typedef unsigned long long ull;
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void Out(int a){
    if(a<0) putchar('-'),a=-a;
    if(a>=10) Out(a/10);
    putchar(a%10+'0');
}
const int N=500000+5;
int size,root;
struct data{int l,r,v,rnd;}tr[N];
void rturn(int &k){
     int t=tr[k].l;
     tr[k].l=tr[t].r;
     tr[t].r=k;k=t;
}
void lturn(int &k){
     int t=tr[k].r;
     tr[k].r=tr[t].l;
     tr[t].l=k;k=t;
}
void insert(int &k,int x){
	if(k==0){
        size++;k=size;
        tr[k].v=x;tr[k].rnd=rand();
        return;
    }
	if(tr[k].v==x) return;
	else if(x<tr[k].v){
        insert(tr[k].l,x);
        if(tr[tr[k].l].rnd<tr[k].rnd) rturn(k);
    }else{
        insert(tr[k].r,x);
        if(tr[tr[k].r].rnd<tr[k].rnd) lturn(k);
    }
}
int t1,t2;
void dfs1(int k,int x){
	if(!k) return;
	if(x>=tr[k].v){
        t1=tr[k].v;
        dfs1(tr[k].r,x);
    }
	else dfs1(tr[k].l,x);
}
void dfs2(int k,int x){
	if(!k) return;
	if(x<=tr[k].v){
        t2=tr[k].v;
        dfs2(tr[k].l,x);
    }
	else dfs2(tr[k].r,x);
}
int main(){
    root=size=0;
    int n=read(),ans=0;
    for(int i=1;i<=n;i++){
        int x=read();
        t1=-inf;t2=inf;
        dfs1(root,x);
        dfs2(root,x);
        if(i!=1) ans+=min(x-t1,t2-x);
        else ans+=x;
        insert(root,x);
    }
    Out(ans);puts("");
    return 0;
}
posted @ 2017-10-08 20:48  江南何采莲  阅读(207)  评论(0编辑  收藏  举报