1588. [HNOI2002]营业额统计【平衡树-splay 或 线段树】
Description
营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。 输入输出要求
Input
Output
输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。
Sample Input
5
1
2
5
4
6
Sample Output
HINT
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
第一个为线段树做法第二个为平衡树做法
线段树:
设每天的营业额在线段树数组中的下标为他本身的值
然后每次输入一个数时我们先在这个数的左边的区间查找最大值
再在右边的区间查找最小值
(这意味着我们要找比这个数小的最大值和比这个数大的最小值)
然后比较两者取差的绝对值最小的加到Ans里即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define MAXN (32767+5)
#define MAX (2000000)
using namespace std; struct node
{
int max,min;
}Segt[MAX*+]; int n,a[MAXN],INF,ans; void Update(int node,int l,int r,int x,int k)
{
if (l==r)
Segt[node].max=Segt[node].min=k;
else
{
int mid=(l+r)/;
if (x<=mid) Update(node*,l,mid,x,k);
if (x>mid) Update(node*+,mid+,r,x,k);
Segt[node].max=max(Segt[node*].max,
Segt[node*+].max);
Segt[node].min=min(Segt[node*].min,
Segt[node*+].min);
}
} int QueryMax(int node,int l,int r,int l1,int r1)
{
if (l>r1||r<l1)
return -INF;
if (l1<=l && r<=r1)
return Segt[node].max;
int mid=(l+r)/;
return max(QueryMax(node*,l,mid,l1,r1),
QueryMax(node*+,mid+,r,l1,r1));
} int QueryMin(int node,int l,int r,int l1,int r1)
{
if (l>r1||r<l1)
return INF;
if (l1<=l && r<=r1)
return Segt[node].min;
int mid=(l+r)/;
return min(QueryMin(node*,l,mid,l1,r1),
QueryMin(node*+,mid+,r,l1,r1));
} int main()
{
memset(&INF,0x7f,sizeof(INF));
for (register int i=;i<=;++i)
Segt[i].min=INF,Segt[i].max=-INF; struct node Segt;
Segt.min=INF;
Segt.max=-INF;
scanf("%d",&n);
for (int i=;i<=n;++i)
{
scanf("%d",&a[i]);
if (i==)
{
Update(,,MAX,a[i]+MAX/,a[i]+MAX/);
ans+=a[i];
continue;
}
int x=QueryMax(,,MAX,,a[i]+MAX/)-MAX/;
int y=QueryMin(,,MAX,a[i]+MAX/,MAX)-MAX/;
Update(,,MAX,a[i]+MAX/,a[i]+MAX/);
ans+=min(abs(a[i]-x),abs(a[i]-y));
}
printf("%d",ans);
}
平衡树:
近乎Splay裸题了……
一天天插入数字,然后查询前驱和后继累加最小值就好了
注意若当前天营业额在之前出现过时(即为Cnt>1)就不用累加了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define MAXN (50000)
using namespace std; int Cnt[MAXN];
int Size[MAXN];
int Key[MAXN];
int Father[MAXN];
int Son[MAXN][];
int SIZE,ROOT;
int INF; void Clear(int x)
{
Cnt[x]=Size[x]=Key[x]=Father[x]=Son[x][]=Son[x][]=;
} void Update(int x)
{
if (x)
{
Size[x]+=Cnt[x];
if (Son[x][]) Size[x]+=Cnt[Son[x][]];
if (Son[x][]) Size[x]+=Cnt[Son[x][]];
}
} int Get(int x)
{
return Son[Father[x]][]==x;
} void Rotate(int x)
{
int fa=Father[x];
int fafa=Father[fa];
int wh=Get(x);
Father[fa]=x;
Son[fa][wh]=Son[x][wh^];
if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
Son[x][wh^]=fa;
Father[x]=fafa;
if (fafa) Son[fafa][Son[fafa][]==fa]=x;
Update(fa);
Update(x);
} void Splay(int x)
{
for (int fa;fa=Father[x];Rotate(x))
if (Father[fa])
Rotate(Get(x)==Get(fa)?fa:x);
ROOT=x;
} void Insert(int x)
{
if (ROOT==)
{
ROOT=++SIZE;
Key[SIZE]=x;
Cnt[SIZE]=Size[SIZE]=;
return;
}
int now=ROOT,fa=;
while ()
{
if(Key[now]==x)
{
++Cnt[now];
Update(now);
Splay(now);
return;
}
fa=now;now=Son[now][x>Key[now]];
if (now==)
{
++SIZE;
Key[SIZE]=x;
Cnt[SIZE]=Size[SIZE]=;
Father[SIZE]=fa;
Son[fa][x>Key[fa]]=SIZE;
Update(fa);
Splay(SIZE);
return;
}
}
} int Pre()
{
int now=Son[ROOT][];
if (now==) return INF;
while (Son[now][])
now=Son[now][];
return Key[now];
} int Next()
{
int now=Son[ROOT][];
if (now==) return INF;
while (Son[now][])
now=Son[now][];
return Key[now];
} int main()
{
int n,x,Ans=;
memset(&INF,0x7f,sizeof(INF));
scanf("%d",&n);
for (int i=;i<=n;++i)
{
scanf("%d",&x);
Insert(x);
if (i==)
Ans+=x;
else
if (Cnt[ROOT]<=)
Ans+=min(abs(x-Pre()),abs(x-Next()));
}
printf("%d",Ans);
}
1588. [HNOI2002]营业额统计【平衡树-splay 或 线段树】的更多相关文章
- BZOJ 1588: [HNOI2002]营业额统计 双向链表 / splay / treap
1588: [HNOI2002]营业额统计 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger ...
- bzoj 1588: [HNOI2002]营业额统计(splay入门)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1588 题解:这题如果用普通的bst的话是可以过时间差不多4s左右如果用splay的话是14 ...
- 数据结构:(平衡树,链表)BZOJ 1588[HNOI2002]营业额统计
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 12173 Solved: 4354[Submit][Sta ...
- 1588: [HNOI2002]营业额统计 (splay tree)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 5783 Solved: 1859[Submit][Stat ...
- Bzoj 1588: [HNOI2002]营业额统计(splay)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...
- BZOJ 1588: [HNOI2002]营业额统计
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 14396 Solved: 5521[Submit][Sta ...
- 1588: [HNOI2002]营业额统计
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 9203 Solved: 3097[Submit][Stat ...
- 2018.07.06 BZOJ 1588: HNOI2002营业额统计(非旋treap)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...
- bzoj 1588: [HNOI2002]营业额统计 treap
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 13902 Solved: 5225[Submit][Sta ...
- BZOJ 1588: [HNOI2002]营业额统计 双向链表
BZOJ 1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 9619 Solved: 3287 题目连接 ht ...
随机推荐
- 来一波Linux中查看cpu、磁盘、内存、网络的命令
转载请注明出处. 如果想远程管理服务器就有远程管理卡,比如Dell idRAC,HP ILO,IBM IMM 查看硬件的温度/风扇转速,电脑有撸大师,服务器就有ipmitool.使用ipmitool实 ...
- git pull和git pull --rebase的使用
使用下面的关系区别这两个操作: git pull = git fetch + git merge git pull --rebase = git fetch + git rebase 现在来看看git ...
- ETL第一篇(Kettle Spoon) 初遇
ETL第一篇(Kettle Spoon) 初遇 ETL第二篇 调用webservice 简介 Kettle 是一款国外开源的 ETL 工具,纯 Java 编写,绿色无需安装,数据抽取高效稳定(数据迁移 ...
- git 命令合并分支代码
git 命令合并分支代码 对于复杂的系统,我们可能要开好几个分支来开发,那么怎样使用git合并分支呢? 合并步骤: 1.进入要合并的分支(如开发分支合并到master,则进入master目录) git ...
- Oracle数据库的监控及数据维护
目前Oracle数据库的管理,数据查询等都需要安装Oracle软件或安装Oracle Client等,远程访问都需要先登录到服务器等繁琐的操作.如果是开发团队,那么每个开发,测试,管理人员都要经历这个 ...
- input textarea监听鼠标粘贴
发现一个问题,在input/textarea中如果是鼠标粘贴内容进去,发现判断不了value的改变,html代码如下: <!doctype html> <html> <h ...
- CF961F k-substrings
题意 给定一个字符串 \(S\) 求所有的 \(S[i,n-i+1]\) 的 \(border\) 长度(最长的前缀等于后缀),要求长度是奇数 \(n\le 10^6\) Sol 首先发现每次求的串都 ...
- SPOJ:SUBLEX - Lexicographical Substring Search
题面 第一行给定主串\((len<=90000)\) 第二行给定询问个数\(T<=500\) 随后给出\(T\)行\(T\)个询问,每次询问排名第\(k\)小的串,范围在\(int\)内 ...
- P1025[SCOI2009]游戏
windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按 顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对应的数字.然后又在新的 ...
- 使用react——解决this.props.history.push无法跳转的问题
转自: https://blog.csdn.net/yingzizizizizizzz/article/details/78751305 场景: 一个组件中,含有ul展开数组的组件,在每一行中,都能点 ...