【Vijos1459】车展
来源:互联网 发布:中国电信4g网络制式 编辑:程序博客网 时间:2024/06/10 09:00
【Description】
遥控车是在是太漂亮了,韵韵的好朋友都想来参观,所以游乐园决定举办m次车展。车库里共有n辆车,从左到右依次编号为1,2,…,n,每辆车都有一个展台。刚开始每个展台都有一个唯一的高度h[i]。主管已经列好一张单子:
L1 R1
L2 R2
…
Lm Rm
单子上的(Li,Ri)表示第i次车展将要展出编号从Li到Ri的车。
为了更加美观,展览时需要调整展台的高度,使参展所有展台的高度相等。展台的高度增加或减少1都需花费1秒时间。由于管理员只有一个人,所以只好对每个展台依次操作。每次展览结束后,展台高度自动恢复到初始高度。
请告诉管理员为了举办所有展览,他最少需要花多少时间将展台调整好。
【Input】
第一行为两个正整数n、m。
第二行共n个非负整数,表示第i辆车展台的高度h[i]。
接下来m行每行2个整数Li、Ri(Li≤Ri)。
【Output】
一个正整数,调整展台总用时的最小值。
【Sample Input】
6 44 1 2 13 0 91 52 63 42 2
【Sample Output】
48
【题解】
看到题目的时候以为求平均数结果看到样例就不对。很简单的道理,给你一个数据:
1 1000 1000 1000
将四个数都换成750(平均数750.25)明显没有将1换成1000的时间短。然后我们就要考虑这个数是哪一个。参考这里Vijos1459 车展,我们可以知道就是要求中位数。接下来就是实现的问题了,上方博文中给出了一种巧妙的
对于50%的数据 n≤500,m≤1000;
对于80%的数据 n≤1000,m≤100000;
对于100%的数据n≤1000,m≤200000;
答案在2^64以内。
可以知道在规定时间内可以运行完。
参考代码如下:
type treap = record rnd,size,w,val:longint; //rnd记录优先,size记录子树大小,w记录和本节点数值相同的点的个数,val记录节点的值 l,r:longint; //l和r分别是左儿子和右儿子编号 sum:int64; //以此节点为根的子树中所有值的总和 end;var n,m,root,cnt:longint; tot,anstot,tmp,num:int64; h:array[0..1010] of longint; ans:array[0..1010,0..1010] of longint; tree:array[0..1010] of treap;procedure init; //读入 var i:longint; begin readln(n,m); for i:=1 to n do read(h[i]); readln; end;procedure update(k:longint); //维护节点 begin tree[k].size:=tree[tree[k].l].size+tree[tree[k].r].size+tree[k].w; tree[k].sum:=tree[tree[k].l].sum+tree[tree[k].r].sum+tree[k].val*tree[k].w; end;procedure right_rotation(var k:longint); //右旋 var tmp:longint; begin tmp:=tree[k].l; tree[k].l:=tree[tmp].r; tree[tmp].r:=k; update(k); update(tmp); k:=tmp; end;procedure left_rotation(var k:longint); //左旋 var tmp:longint; begin tmp:=tree[k].r; tree[k].r:=tree[tmp].l; tree[tmp].l:=k; update(k); update(tmp); k:=tmp; end;procedure insert(var k:longint; x:longint); //插入新节点 begin if (k=0) then begin inc(cnt); k:=cnt; tree[k].size:=1; tree[k].w:=1; tree[k].sum:=x; tree[k].val:=x; tree[k].rnd:=random(10000); tree[k].l:=0; tree[k].r:=0; exit; end; inc(tree[k].size); inc(tree[k].sum,x); if tree[k].val=x then begin inc(tree[k].w); exit; end; if x>tree[k].val then begin insert(tree[k].r,x); if tree[tree[k].r].rnd<tree[k].rnd then left_rotation(k); exit; end; if x<tree[k].val then begin insert(tree[k].l,x); if tree[tree[k].l].rnd<tree[k].rnd then right_rotation(k); end; end;function query(k,val:longint):longint; //查找中位数并记录相关值 begin if val<=tree[tree[k].l].size then exit(query(tree[k].l,val)); if (val>tree[tree[k].l].size+tree[k].w) then begin inc(tmp,tree[tree[k].l].sum+tree[k].w*tree[k].val); inc(num,tree[tree[k].l].size+tree[k].w); exit(query(tree[k].r,val-tree[tree[k].l].size-tree[k].w)); end; inc(tmp,tree[tree[k].l].sum); inc(num,tree[tree[k].l].size); exit(tree[k].val); end;procedure prep; //预先算出每个区间内的答案 var i,j,ave:longint; begin for i:=1 to n do begin //分别以1~n为根建树 cnt:=0; root:=0; tot:=0; for j:=i to n do begin inc(tot,h[j]); insert(root,h[j]); tmp:=0; num:=0; ave:=query(root,(j-i+2) div 2); inc(ans[i,j],num*ave-tmp); inc(ans[i,j],tot-tmp-(j-i+1-num)*ave); end; end; end;procedure main; var i,a,b:longint; begin for i:=1 to m do begin readln(a,b); anstot:=anstot+ans[a,b]; end; writeln(anstot); end;begin init; prep; main;end.
参考资料:
1.Vijos 车展-yywyzdzr-博客频道-CSDN.NET
2.【vijos1459】车展|treap|中位数|HZWER:WE are OIers
- Vijos1459 车展
- 【Vijos1459】车展
- 【vijos1459】车展
- [vijos1459]车展(splay)
- 车展
- 车展
- html5 车展
- 北京车展众模特,北京车展众香车美女,2008车展
- 广州车展美女
- 2008车展美女车模
- 2009上海车展
- 2010北美车展
- 车展与云相机
- 怎么样看待上海车展?
- 车展 (Standard IO)
- 购物车展示
- 北京国际车展全球第几
- 2012 五一放假游车展
- 关于Java的File.separator
- Table表格做登陆页面
- linux查找函数/查看文件夹size/tab转4空格 命令
- UITextView实现placeholder的猥琐做法
- 由cache"引起"的内存问题——记录Linux的Cache Memory(缓存内存)机制
- 【Vijos1459】车展
- 部分显示效果汇总
- Best Time to Buy and Sell Stock II
- IntelliJIDEA中如何导入额外的jar包
- 南邮 OJ 1882 C. 数字串划分
- Form表单做调查表
- 计算机系统里面的时间
- 广播即时通信src和des
- Mac OS 下命令行使用Git 管理iOS代码