H - 营业额统计
解题方法:
每次找 min(大于a的最小值, 小于a 的最大值)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
using namespace std;
const int maxn=500010;
const int inf=0x3f3f3f3f;
struct SplayTree
{
int rt,id;
int son[maxn][2],val[maxn],pre[maxn];
void Rotate(int x,int c)
{
int y=pre[x];
son[y][!c]=son[x][c];
pre[son[x][c]]=y;
pre[x]=pre[y];
if(pre[y]) son[pre[y]][son[pre[y]][1]==y]=x;
son[x][c]=y;
pre[y]=x;
}
void Splay(int x,int goal)
{
while(pre[x]!=goal)
{
if(pre[pre[x]]==goal)
{
if(son[pre[x]][1]==x)
Rotate(x,0);
else
Rotate(x,1);
}
else{
int y=pre[x];
int z=pre[y];
if(son[z][0]==y){
if(son[y][0]==x){
Rotate(y,1),Rotate(x,1);
}
else {
Rotate(x,0),Rotate(x,1);
}
}
else {
if(son[y][1]==x){
Rotate(y,0),Rotate(x,0);
}
else {
Rotate(x,1),Rotate(x,0);
}
}
}
}
if(goal==0) rt=x;
}
void Newnode(int f,int &x,int a)
{
x=++id;
pre[x]=f;
val[x]=a;
son[x][0]=0,son[x][1]=0;
}
void Init()
{
id=0;
Newnode(0,rt,-inf);
Newnode(rt,son[rt][1],inf);
}
void Insert(int a)
{
int x=rt;
while(son[x][val[x]<a]) x=son[x][val[x]<a];
Newnode(x,son[x][val[x]<a],a);
Splay(id,0);
}
int fx_min(int a)
{
int x=rt;
int Min=inf;
while(x){
if(val[x]==a) return a;
if(val[x]>a) Min=min(Min,val[x]);
if(val[x]>a) x=son[x][0];
else
x=son[x][1];
}
return Min;
}
int fx_max(int a)
{
int x=rt;
int Max=-inf;
while(x){
if(val[x]==a) return a;
if(val[x]<a) Max=max(Max,val[x]);
if(val[x]<a)
x=son[x][1];
else
x=son[x][0];
}
return Max;
}
}spy;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // ONLINE_JUDGE
int n,a,ans;
scanf("%d%d",&n,&a);
spy.Init();
spy.Insert(a);
ans=a;
while(--n)
{
if(scanf("%d",&a)==EOF) a=0;
ans+=min(fabs(a-spy.fx_min(a)),fabs(a-spy.fx_max(a)));
spy.Insert(a);
}
printf("%d\n",ans);
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-31 14:39:55