裸地平衡树,应该可以用各种平衡树。
就是插入一个节点之后求其前驱和后继,然后做差取绝对值最小的加到答案上。第一个节点直接加在答案上。
数据似乎有问题,要在输入的时候特殊处理,。。。我直接看了DISCUSS。。。。
1588: [HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4504 Solved: 1433
[ Submit][ Status][ Discuss]
Description
营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。 输入输出要求
Input
第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数 ,表示第i天公司的营业额。
Output
输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。
Sample Input
6
5
1
2
5
4
6
5
1
2
5
4
6
Sample Output
12
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;
#define MAXN 500000
#define INF 0x3FFFFFF
//内存
int next[MAXN];
struct nodes
{
int ch[2],f;
int key;
}node[MAXN];
int pos[MAXN];
void init()
{
for(int i=0;i<MAXN-10;i++)
next[i]=i+1;
}
int newnode(int key)
{
int p=next[0];
next[0]=next[p];
node[p].key=key;
node[p].ch[0]=node[p].ch[1]=node[p].f=0;
return p;
}
void delnode(int p)
{
next[p]=next[0];
next[0]=p;
}
struct spt
{
int root;
void clear()
{
root=0;
}
void rotate(int x,int c)
{
int y=node[x].f;
node[y].ch[!c]=node[x].ch[c];
if(node[x].ch[c])
node[node[x].ch[c]].f=y;
node[x].f=node[y].f;
if(node[y].f)
{
if(node[node[y].f].ch[0]==y)
node[node[y].f].ch[0]=x;
else
node[node[y].f].ch[1]=x;
}
node[x].ch[c]=y;
node[y].f=x;
if(y==root) root=x;
}
void splay(int x,int f)
{
for(;node[x].f!=f;)
{
if(node[node[x].f].f==f)
{
if(node[node[x].f].ch[0]==x)
rotate(x,1);
else
rotate(x,0);
}
else
{
int y=node[x].f;
int z=node[y].f;
if(node[z].ch[0]==y)
{
if(node[y].ch[0]==x)
rotate(y,1),rotate(x,1);
else
rotate(x,0),rotate(x,1);
}
else
{
if(node[y].ch[1]==x)
rotate(y,0),rotate(x,0);
else
rotate(x,1),rotate(x,0);
}
}
}
if(!f) root=x;
}
void insert(int key,int rt)
{
int p=rt,y=0;
while(1)
{
if(!p)
{
p=newnode(key);
node[p].f=y;
if(y)
node[y].ch[key>node[y].key]=p;
splay(p,0);
break;
}
y=p;
if(key<=node[p].key)
p=node[p].ch[0];
else
p=node[p].ch[1];
}
}
int getpre(int p)
{
if(!node[p].ch[0]) return 0;
p=node[p].ch[0];
while(node[p].ch[1])
p=node[p].ch[1];
return p;
}
int getbeh(int p)
{
if(!node[p].ch[1]) return 0;
p=node[p].ch[1];
while(node[p].ch[0])
p=node[p].ch[0];
return p;
}
void del(int p)
{
if(!p) return;
del(node[p].ch[0]);
del(node[p].ch[1]);
delnode(p);
}
};
spt s1;
int n,m,a;
int ans;
int main()
{
init();
while(~scanf("%d",&n))
{
s1.clear();
ans=0;
for(int i=0;i<n;i++)
{
if(scanf("%d",&a)==EOF) a=0;
s1.insert(a,s1.root);
int p1=s1.getpre(s1.root);
int p2=s1.getbeh(s1.root);
p1=p1!=0?abs(node[p1].key-a):INF;
p2=p2!=0?abs(node[p2].key-a):INF;
if(i==0)
ans+=a;
else
ans+=min(p1,p2);
}
s1.del(s1.root);
printf("%d\n",ans);
}
return 0;
}