Description
营业额统计Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值。当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。
输入输出要求
Input
第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的
n
行每行有一个整数(有可能有负数) ,表示第
天数
n<=32767
,每天的营业额
ai<=1,000,000
。
最后结果
T<=231
Output
输出文件仅有一个正整数,即
∑每天最小的波动值
。结果小于
231
。
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
该题数据bug已修复.—-2016.5.15
Source
思路
BST裸题,只需要插入一个点,求它的前驱和后继,然后比较这个点与前驱和后继差值的大小。
代码(splay)
#include <cstdio>
#include <algorithm>
#include <cstring>
const int maxn=100000;
int ans;
struct splay_tree
{
int son[2][maxn+10],fa[maxn+10],tot,val[maxn+10],root;
inline int mem()
{
val[0]=-1;
return 0;
}
inline int t(int now)
{
return son[1][fa[now]]==now;
}
inline int rotate(int now)
{
int k=t(now),father=fa[now];
if(son[!k][now])
{
fa[son[!k][now]]=father;
}
son[k][father]=son[!k][now];
son[!k][now]=father;
fa[now]=fa[father];
if(fa[father])
{
son[t(father)][fa[father]]=now;
}
fa[father]=now;
return 0;
}
inline int splay(int now,int c)
{
while(fa[now]!=c)
{
int f=fa[now],a=fa[f];
if(a==c)
{
rotate(now);
}
else if(t(now)==t(f))
{
rotate(f);
rotate(now);
}
else
{
rotate(now);
rotate(now);
}
}
if(!c)
{
root=now;
}
return 0;
}
inline int insert(int v)
{
++tot;
val[tot]=v;
if(!root)
{
root=1;
fa[1]=0;
return 0;
}
int now=root;
while(now)
{
int t=(val[now]<v);
if(!son[t][now])
{
son[t][now]=tot;
fa[tot]=now;
break;
}
now=son[t][now];
}
splay(tot,0);
return 0;
}
inline int prei(int now)
{
splay(now,0);
int x=son[0][now];
while(son[1][x])
{
x=son[1][x];
}
return x;
}
inline int nexti(int now)
{
splay(now,0);
int x=son[1][now];
while(son[0][x])
{
x=son[0][x];
}
return x;
}
inline int calc(int x)
{
insert(x);
int p=val[prei(tot)],n=val[nexti(tot)];
x=val[root];
if((p==-1)&&(n==-1))
{
ans+=x;
}
else if(p==-1)
{
ans+=n-x;
}
else if(n==-1)
{
ans+=x-p;
}
else
{
ans+=std::min(n-x,x-p);
}
return 0;
}
};
splay_tree st;
int n,a;
int main()
{
scanf("%d",&n);
st.mem();
while(scanf("%d",&a)!=EOF)
{
st.calc(a);
--n;
}
while(n--)
{
st.calc(0);
}
printf("%d\n",ans);
return 0;
}
代码(fhq_treap)
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
typedef pair<int,int> pii;
const int sor='y'+'c'+'z'+' '+'i'+'s'+' '+'o'+'u'+'r'+' '+'s'+'u'+'n';
struct treap
{
int tot,root,son[3000009][2],size[3000009],val[3000009];
int mem()
{
memset(val,255,sizeof(val));
return 0;
}
int updata(int a)
{
return size[a]=size[son[a][0]]+size[son[a][1]]+1;
}
int random(int limit)
{
return rand()%limit+1;
}
int merge(int a,int b)
{
if ((a==0)||(b==0))
{
return a+b;
}
if (random(size[a]+size[b])<=size[a])
{
son[a][1]=merge(son[a][1],b);
updata(a);
return a;
}
else
{
son[b][0]=merge(a,son[b][0]);
updata(b);
return b;
}
}
pii split(int a,int k)
{
if (size[a]==k)
{
return make_pair(a,0);
}
if (k==0)
{
return make_pair(0,a);
}
pii t;
if (size[son[a][0]]>=k)
{
t=split(son[a][0],k);
son[a][0]=t.second;
updata(a);
return make_pair(t.first,a);
}
else
{
t=split(son[a][1],k-size[son[a][0]]-1);
son[a][1]=t.first;
updata(a);
return make_pair(a,t.second);
}
}
int rank(int v)
{
int i=root,ans=0;
while (i!=0)
{
if (val[i]>=v)
{
i=son[i][0];
}
else
{
ans+=size[son[i][0]]+1;
i=son[i][1];
}
}
return ans+1;
}
int id(int v,int k)
{
if (k==0)
{
return 0;
}
if (size[son[v][0]]>=k)
{
return id(son[v][0],k);
}
if (size[son[v][0]]+1==k)
{
return v;
}
return id(son[v][1],k-size[son[v][0]]-1);
}
int getval(int v)
{
return val[id(root,v)];
}
int pre(int v)
{
return val[id(root,rank(v)-1)];
}
int next(int v)
{
return val[id(root,rank(v)+1)];
}
int insert(int v)
{
tot++;
son[tot][0]=son[tot][1]=0;
val[tot]=v;
size[tot]=1;
pii t=split(root,rank(v)-1);
root=merge(merge(t.first,tot),t.second);
return root;
}
int adelete(int v)
{
int x;
x=rank(v);
pii s,t;
s=split(root,x-1);
t=split(s.second,1);
root=merge(s.first,t.second);
return root;
}
};
treap tree;
int n,x,pr,ne,ans;
int main()
{
tree.mem();
srand(sor);
scanf("%d",&n);
while (n--)
{
scanf("%d",&x);
tree.insert(x);
pr=tree.pre(x);
ne=tree.next(x);
if (pr==-1&&ne==-1)
{
ans+=x;
continue;
}
if (ne==-1)
{
ans+=abs(pr-x);
continue;
}
if (pr==-1)
{
ans+=abs(ne-x);
continue;
}
ans+=min(abs(ne-x),abs(pr-x));
}
printf("%d",ans);
return 0;
}