bzoj 1588 splay树入门题
来源:互联网 发布:淘宝打折网 编辑:程序博客网 时间:2024/06/05 06:30
1588: [HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 8725 Solved: 2896
[Submit][Status]
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
HINT
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
set容器写法:
Accepted1936 kb148 msC++/Edit1052 B#include<stdio.h>#include<iostream>#include<set>using namespace std;set<int>g;int min(int a,int b){ return a<b?a:b;}int main(){ int n,a,b,c,sum,i; while(scanf("%d",&n)!=EOF) { if(scanf("%d",&a) == EOF) a = 0;//这样输入才能A,直接scanf("%d",&a)就WA了,费解。好吧,据说是因为数据丢失。 g.clear(); sum=0; sum+=a; g.insert(a); for(i=2;i<=n;i++) { if(scanf("%d",&a) == EOF) a = 0; set<int>::iterator it1,it2=g.lower_bound(a); // printf("2=%d\n",*it2); if(it2==g.end()) { it2--; sum+=a-(*it2); } else if(it2!=g.begin()) { c=(*it2)-a; it1=--it2; b=a-(*it1); sum+=min(b,c); } else sum+=(*it2)-a; g.insert(a); } printf("%d\n",sum); } return 0;}splay树写法:
Accepted2836 kb156 msC++/Edit3080 B
#include<stdio.h>#include<string.h>#define N 100005#include<iostream>#define inf 0x3fffffffint pre[N],key[N],ch[N][2],root,tot;//分别表示父结点,键值,左右孩子(0为左孩子,1为右孩子),根结点,结点数量//新建一个结点void newnode(int &r,int father,int k){ r=++tot; pre[r]=father; key[r]=k; ch[r][0]=ch[r][1]=0;//左右孩子为空}//旋转,kind为1为右旋,kind为0为左旋void Rotate(int x,int kind){ int y=pre[x]; ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; //如果父节点不是根结点,则要和父节点的父节点连接起来 if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x;}//Splay调整,将根为r的子树调整为goalvoid splay(int r,int goal){ while(pre[r]!=goal) {//当前节点不是根节点 if(pre[pre[r]]==goal)//父节点是根节点 Rotate(r,ch[pre[r]][0]==r); else { int y=pre[r]; int kind=ch[pre[y]][0]==y; //两个方向不同,则先左旋再右旋 if(ch[y][kind]==r) { Rotate(r,!kind); Rotate(r,kind); } //两个方向相同,相同方向连续两次 else { Rotate(y,kind); Rotate(r,kind); } } } //更新根结点 if(goal==0) root=r;}int Insert(int k){ int r=root; while(ch[r][key[r]<k]) { if(key[r]==k) {//不重复插入 splay(r,0); return 0; } r=ch[r][key[r]<k]; } newnode(ch[r][key[r]<k],r,k); //将新插入的结点更新至根结点 splay(ch[r][key[r]<k],0); return 1;}//找前驱,即左子树的最右结点int getpre(int x){ int tmp=ch[x][0]; if(tmp==0) return inf; while(ch[tmp][1]) tmp=ch[tmp][1]; return key[x]-key[tmp];}//找后继,即右子树的最左结点int getnext(int x){ int tmp=ch[x][1]; if(tmp==0) return inf; while(ch[tmp][0]) tmp=ch[tmp][0]; return key[tmp]-key[x];}int min(int a,int b){ return a<b?a:b;}int main(){ int i,n,a,ans; while(scanf("%d",&n)!=EOF) { root=tot=0; ans=0; for(i=1;i<=n;i++) { if(scanf("%d",&a)==EOF) a=0; if(i==1) { ans+=a; newnode(root,0,a); continue; } if(Insert(a)==0) continue; ans+=min(getnext(root),getpre(root)); } printf("%d\n",ans); } return 0;}
0 0
- bzoj 1588 splay树入门题
- BZOJ 1588 Splay 入门
- BZOJ 1588 Splay树
- bzoj 1588 splay入门题 (插入,查询)
- BZOJ 1588 营业额统计(Splay树入门)
- BZOJ 1588 营业额统计 (Splay入门题 插入 找前驱后继)
- bzoj 1588 splay 模板
- BZOJ 1588 splay
- bzoj 1208 宠物收养所 Splay入门
- bzoj 1503 郁闷的出纳员 Splay入门
- bzoj 1588 营业额统计 splay
- BZOJ 1588 营业额统计 Splay
- BZOJ 1588 营业额统计 Splay
- BZOJ 1588 营业额统计 Splay
- bzoj 1500 splay伸展树
- BZOJ 1588 BZOJ 1503 平衡数splay
- Splay入门题+1588: [HNOI2002]营业额统计
- 1588: [HNOI2002]营业额统计(Splay树入门)
- socket通信的多进程编程:
- ARM汇编 .word 解析
- 使用PreparedStatement的execute方法需要注意的问题
- poj 3080 kmp模板
- AFNetworking源码之AFSecurityPolicy模块
- bzoj 1588 splay树入门题
- B BL指令浅析
- 跨域登录
- 设计模式之桥接模式-bridge
- linux虚拟机增加硬盘存储
- Mysql设置自增长主键的初始值
- UIScrollView的基本属性和协议方法
- .NET基础知识
- GUN ASM概述