1. 程式人生 > >Luogu P2234 [HNOI2002]營業額統計

Luogu P2234 [HNOI2002]營業額統計

https://www.luogu.org/problemnew/show/P2234

題目描述

Tiger最近被公司升任為營業部經理,他上任後接受公司交給的第一項任務便是統計並分析公司成立以來的營業情況。

Tiger拿出了公司的賬本,賬本上記錄了公司成立以來每天的營業額。分析營業情況是一項相當複雜的工作。由於節假日,大減價或者是其他情況的時候,營業額會出現一定的波動,當然一定的波動是能夠接受的,但是在某些時候營業額突變得很高或是很低,這就證明公司此時的經營狀況出現了問題。經濟管理學上定義了一種最小波動值來衡量這種情況:

當最小波動值越大時,就說明營業情況越不穩定。

而分析整個公司的從成立到現在營業情況是否穩定,只需要把每一天的最小波動值加起來就可以了。你的任務就是編寫一個程式幫助Tiger來計算這一個值。

第一天的最小波動值為第一天的營業額。

該天的最小波動值=min{|該天以前某一天的營業額-該天營業額|}。

輸入輸出格式

輸入格式:

 

輸入由檔案’turnover.in’讀入。

第一行為正整數n(n<=32767) ,表示該公司從成立一直到現在的天數,接下來的n行每行有一個整數ai(|ai|<=1000000) ,表示第i天公司的營業額,可能存在負數。

 

輸出格式:

 

 

輸入輸出樣例

輸入樣例#1: 複製

6
5
1
2
5
4
6

輸出樣例#1: 複製

12

說明

結果說明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12

這題不就是treap模板題的一部分?

https://mp.csdn.net/postedit/84026947鏈一鏈,我自認為寫的最詳細的部落格

#include<cstdio>
#include<iostream>
#include<ctime>
#include<algorithm>
using namespace std;

const int N=1e6+5;
int n,r,ans;

struct A
{
	int tre[N],cnt,hea[N],lc[N],rc[N];
	inline void zig(int &x,int y)
	{
		lc[x]=rc[y],rc[y]=x,x=y;
	}
	
	inline void zag(int &x,int y)
	{
		rc[x]=lc[y],lc[y]=x,x=y;
	}
	
	void ins(int &x,int k)
	{
		if(!x) 
		{
			x=++cnt,tre[x]=k,hea[x]=rand();
			return;
		}
		if(k<tre[x]) 
		{
			ins(lc[x],k);
			if(hea[lc[x]]<hea[x]) zig(x,lc[x]);
		}else 
		{
			ins(rc[x],k);
			if(hea[rc[x]]<hea[x]) zag(x,rc[x]);
		}
	}
	
	int pre(int x,int k)
	{
		int ret=-2e9;
		while(x) 
		{
			if(tre[x]>k) x=lc[x];
				else ret=max(ret,tre[x]),x=rc[x]; 
		} 
		return ret;
	}
	
	int nxt(int x,int k)
	{
		int ret=2e9;
		while(x)
		{
			if(tre[x]<k) x=rc[x];
				else ret=min(ret,tre[x]),x=lc[x];
		}
		return ret;
	}
}treap;
int main()
{
	srand(time(NULL));
	scanf("%d",&n);
	n--;
	int x; scanf("%d",&x);
	treap.ins(r,x);
	ans+=x;
	while(n--)
	{
		scanf("%d",&x);	
		int a1=treap.pre(r,x),a2=treap.nxt(r,x);
		ans+=min(x-a1,a2-x);
		treap.ins(r,x);
	}	
	printf("%d",ans);
	return 0;
}