1112: [POI2008]砖块Klo
时间:2022-05-08
本文章向大家介绍1112: [POI2008]砖块Klo,主要内容包括1112: [POI2008]砖块Klo、Description、Input、Output、Sample Input、Sample Output、HINT、Source、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
1112: [POI2008]砖块Klo
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1245 Solved: 426
Description
N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任务.
Input
第一行给出N,K. (1 ≤ k ≤ n ≤ 100000), 下面N行,每行代表这柱砖的高度.0 ≤ hi ≤ 1000000
Output
最小的动作次数
Sample Input
5 3 3 9 2 3 1
Sample Output
2
HINT
原题还要求输出结束状态时,每柱砖的高度.本题略去.
Source
题解:(呵呵呵我会说我逗到了用Splay做这题的地步么= =)
首先,看这道题,对于某个高度序列而言,很明显将所有高度都变为中位数代价最小
我觉得任何一个数竞党都该知道怎么样可以让下列式子值最小——
( sum_{i=1}^{N} left | x-x_i right | ) 其中,( x_1 leq x_2 leq x_3 ... leq x_N ) 显然,当N为奇数时, ( x=x_frac{N+1}{2} ) 当N为偶数时, ( x_frac{N}{2} leq x leq x_frac{N+2}{2} )
然后接下来讨论怎么实现——我们需要一棵平衡树,可以加入和删除值,可以查询指定排名的数位置(用来找中位数),还得可以快速求出当前序列中比中位数大的各个数之和,以及比它小的之和,这样子就很明显需要维护子树大小(用于排名),然后还得维护子树和,然后我为了偷懒就直接来了个splay,每次将中位数splay上来,然后两边的不就是我们要的两边和嘛,然后该怎么办怎么办,别的没了
1 /**************************************************************
2 Problem: 1112
3 User: HansBug
4 Language: Pascal
5 Result: Accepted
6 Time:6156 ms
7 Memory:27636 kb
8 ****************************************************************/
9
10 var
11 i,j,k,m,n,head:longint;
12 l,ans:int64;
13 lef,rig,b:array[0..1000000] of longint;
14 a,c:array[0..1000000] of int64;
15 procedure rt(var x:longint);inline;
16 var f,l:longint;
17 begin
18 if (x=0) or (lef[x]=0) then exit;
19 b[lef[x]]:=b[x];b[x]:=b[rig[lef[x]]]+b[rig[x]]+1;
20 c[lef[x]]:=c[x];c[x]:=c[rig[lef[x]]]+c[rig[x]]+a[x];
21 f:=x;l:=lef[x];
22 lef[f]:=rig[l];
23 rig[l]:=f;
24 x:=l;
25 end;
26 procedure lt(var x:longint);inline;
27 var f,r:longint;
28 begin
29 if (x=0) or (rig[x]=0) then exit;
30 b[rig[x]]:=b[x];b[x]:=b[lef[rig[x]]]+b[lef[x]]+1;
31 c[rig[x]]:=c[x];c[x]:=c[lef[rig[x]]]+c[lef[x]]+a[x];
32 f:=x;r:=rig[x];
33 rig[f]:=lef[r];
34 lef[r]:=f;
35 x:=r;
36 end;
37 procedure splay(var x:longint;y:longint);inline;
38 begin
39 if (x=0) or (y=0) then exit;
40 if y=(b[lef[x]]+1) then exit;
41 if y<(b[lef[x]]+1) then
42 begin
43 if (b[lef[lef[x]]]+1)=y then rt(x) else
44 if y<(b[lef[lef[x]]]+1) then
45 begin
46 splay(lef[lef[x]],y);
47 rt(x);rt(x);
48 end
49 else
50 begin
51 splay(rig[lef[x]],y-b[lef[lef[x]]]-1);
52 lt(lef[x]);rt(x);
53 end;
54 end
55 else
56 begin
57 y:=y-1-b[lef[x]];
58 if y=(b[lef[rig[x]]]+1) then lt(x) else
59 if y<(b[lef[rig[x]]]+1) then
60 begin
61 splay(lef[rig[x]],y);
62 rt(rig[x]);lt(x);
63 end
64 else
65 begin
66 splay(rig[rig[x]],y-1-b[lef[rig[x]]]);
67 lt(x);lt(x);
68 end;
69 end;
70 end;
71 procedure ins(var x:longint;y:longint);inline;
72 begin
73 if x=0 then
74 begin
75 x:=y;
76 exit;
77 end;
78 if a[y]<=a[x] then
79 begin
80 ins(lef[x],y);
81 c[x]:=c[lef[x]]+c[rig[x]]+a[x];
82 b[x]:=b[lef[x]]+b[rig[x]]+1;
83 end
84 else
85 begin
86 ins(rig[x],y);
87 c[x]:=c[lef[x]]+c[rig[x]]+a[x];
88 b[x]:=b[lef[x]]+b[rig[x]]+1;
89 end;
90 end;
91 function getrank(x,y:longint):longint;inline;
92 begin
93 if x=0 then exit(-1);
94 if a[x]=y then exit(b[lef[x]]+1);
95 if y<a[x] then exit(getrank(lef[x],y)) else exit(b[lef[x]]+1+getrank(rig[x],y));
96 end;
97 procedure init(x:longint);inline;
98 begin
99 ins(head,x);
100 splay(head,random(b[head])+1);
101 end;
102 procedure kill(x:longint);inline;
103 begin
104 if x=1 then
105 begin
106 splay(head,2);
107 dec(c[head],c[lef[head]]);
108 dec(b[head]);
109 lef[head]:=0;
110 end
111 else if x=b[head] then
112 begin
113 splay(head,b[head]-1);
114 dec(c[head],c[rig[head]]);
115 dec(b[head]);
116 rig[head]:=0;
117 end
118 else begin
119 splay(head,x+1);
120 splay(lef[head],x-1);
121 dec(c[head],c[rig[lef[head]]]);dec(b[head]);
122 dec(c[lef[head]],c[rig[lef[head]]]);dec(b[lef[head]]);
123 rig[lef[head]]:=0;
124 end;
125 end;
126 begin
127 readln(n,m);randomize;
128 if m<=1 then
129 begin
130 writeln(0);
131 halt;
132 end;
133 for i:=1 to n do
134 begin
135 readln(a[i]);
136 c[i]:=a[i];b[i]:=1;
137 lef[i]:=0;rig[i]:=0;
138 end;
139 head:=0;ans:=maxlongint*maxlongint;
140 for i:=1 to m do init(i);
141 for i:=1 to n-m+1 do
142 begin
143 splay(head,(m+1) div 2);
144 l:=0;
145 if lef[head]<>0 then inc(l,a[head]*b[lef[head]]-c[lef[head]]);
146 if rig[head]<>0 then inc(l,c[rig[head]]-a[head]*b[rig[head]]);
147 if l<ans then ans:=l;
148 if i=(n-m+1) then break;
149 kill(getrank(head,a[i]));
150 init(i+m);
151 end;
152 writeln(ans);
153 readln;
154 end.
- zephir-(9)类和对象2
- 深度学习中的动手实践:在CIFAR-10上进行图像分类
- 数据库中间件 MyCAT源码分析 —— XA分布式事务
- [喵咪Golang(1)]Go语言开篇
- phalcon-进阶篇2(拦截器)
- 【死磕Java并发】—–深入分析synchronized的实现原理
- phalcon-进阶篇1(过滤与清理)
- phalcon-入门篇9(view层基础使用)
- PhalApi视频教程
- 【学术】一文搞懂自编码器及其用途(含代码示例)
- PhalApi-Zip--压缩文件处理类
- PhalApi-Xhprof -- Facebook开源的轻量级PHP性能分析工具
- OpenAI发布8个模拟机器人环境以及一种HER实现,以训练实体机器人模型
- PhalApi-APK--APK文件解包处理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- git 常用命令介绍
- PAT (Basic Level) Practice (中文)1043 输出PATest (20 分)
- PAT (Basic Level) Practice (中文)1047 编程团体赛 (20 分)
- Vue中computed分析
- 半小时搞懂 HTTP、HTTPS和HTTP2
- RestPack Java实现Html转PDF文件
- 六、垃圾回收_判断对象是否存活算法_引用计数法详解
- webpack + express 实现文件精确缓存
- python提取视频中的音频
- Vue3 响应式原理
- vue-mergeable-table 动态生成的可合并行列的表格
- 【GOFLY】基于GO语言gin框架和websocket实现的全开源WEB客服即时通讯管理系统
- edgeXFoundry中modbus通信部署和测试(待续)
- C++面向对象学习之运算符重载(1)
- PAT (Basic Level) Practice (中文)1045 快速排序 (25 分)