[Bzoj1112][POI2008]砖块Klo(splay)
1112: [POI2008]砖块Klo
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2353 Solved: 831
[Submit][Status][Discuss]
Description
N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任务.
Input
第一行给出N,K. (1 ≤ k ≤ n ≤ 100000), 下面N行,每行代表这柱砖的高度.0 ≤ hi ≤ 1000000
Output
最小的动作次数
Sample Input
Sample Output
HINT
原题还要求输出结束状态时,每柱砖的高度.本题略去.
分析:
splay求中位数。
AC代码:
# include <iostream>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long LL;
const int N = 1e5 + ;
LL s[N],ret = 1e18;int n,K,root,cnt;
struct node{
int ch[];
int fa;
int sz;LL val,sum;
node(){}
node(LL val):fa(),sz(),val(val),sum(sum){ch[] = ch[] = ;}
}a[N];
void push(int x)
{
a[x].sz = a[a[x].ch[]].sz + a[a[x].ch[]].sz + ;
a[x].sum = a[a[x].ch[]].sum + a[a[x].ch[]].sum + a[x].val;
}
void rotate(int now,int d)
{
int pre = a[now].fa,g = a[pre].fa,nex = a[now].ch[d];
a[pre].ch[d ^ ] = nex;
if(nex)a[nex].fa = pre;
a[now].fa = g;
if(g)a[g].ch[a[g].ch[] == pre] = now;
a[pre].fa = now;a[now].ch[d] = pre;
push(pre);push(now);
}
void splay(int now)
{
int pre,g;
while(a[now].fa)
{
pre = a[now].fa,g = a[pre].fa;
if(g && !((a[pre].ch[] == now) ^ (a[g].ch[] == pre)))rotate(pre,a[pre].ch[] == now);
rotate(now,a[pre].ch[] == now);
}
root = now;
}
void insert(LL val)
{
if(!root){a[++cnt] = node(val);root = cnt;return;}
int now = root,pre;
while(now)
{
pre = now;
now = a[now].ch[val > a[now].val];
}
a[++cnt] = node(val);a[cnt].fa = pre;
a[pre].ch[val > a[pre].val] = cnt;
splay(cnt);
}
void erase(int now)
{
splay(now);
if(!a[now].ch[] || !a[now].ch[]){root = a[now].ch[] + a[now].ch[];}
else
{
int p = a[now].ch[];
while(a[p].ch[])p = a[p].ch[];
a[p].ch[] = a[now].ch[];
a[a[now].ch[]].fa = p;
root = a[now].ch[];a[root].fa = ;
splay(a[now].ch[]);
}
a[root].fa = ;
}
int find(int k)
{
int now = root;
while(k > )
{
if(a[a[now].ch[]].sz < k){k -= a[a[now].ch[]].sz;k--;if(k > )now = a[now].ch[];}
else now = a[now].ch[];
}
return now;
}
int main()
{
scanf("%d %d",&n,&K);
for(int i = ;i <= n;i++)scanf("%lld",&s[i]);
for(int i = ;i < K;i++)insert(s[i]);
for(int i = K;i <= n;i++)
{
if(i - K)erase(i - K);
insert(s[i]);
int now = find((K + ) >> );
splay(now);
LL s1 = a[a[now].ch[]].sz,s2 = a[a[now].ch[]].sz;
LL pre = a[a[now].ch[]].sum,bef = a[a[now].ch[]].sum;
if(s1 * a[now].val - pre + bef - s2 * a[now].val < ret)ret = s1 * a[now].val - pre + bef - s2 * a[now].val;
}
printf("%lld\n",ret);
}
[Bzoj1112][POI2008]砖块Klo(splay)的更多相关文章
- [BZOJ1112][POI2008]砖块Klo
[BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...
- BZOJ 1112: [POI2008]砖块Klo Splay + 性质分析
Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...
- [BZOJ1112] [POI2008] 砖块Klo (treap)
Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次 ...
- BZOJ1112[POI2008]砖块Klo——非旋转treap
题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...
- 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo
枚举长度为m的所有段,尝试用中位数更新答案. 所以需要数据结构,支持查询k大,以及大于/小于 k大值 的数的和. 平衡树.权值线段树.权值分块什么的随便呢. #include<cstdio> ...
- 【主席树】bzoj1112: [POI2008]砖块Klo
数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...
- 【BZOJ1112】[POI2008]砖块Klo Treap
[BZOJ1112][POI2008]砖块Klo Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出 ...
- 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1245 Solved: 426[Submit][Statu ...
- BZOJ 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1736 Solved: 606[Submit][Statu ...
随机推荐
- shell脚本,创建50个文件,删除50个文件。
[root@localhost ~]# cat create50.sh #!/bin/bash #创建50个文件 ` do touch student$i done echo "创建50个文 ...
- redhat7.3建两个网桥导致mac地址不一致解决办法
将网卡配置文件中加入下面一行参数 NM_CONTROLLED=no
- 51nod——1174 区间中最大的数(ST)
题目链接 给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,对应的数为7 6 3,最大的数 ...
- HDU - 4802 - GPA (水题)
题意: 计算GPA,输入一个数字和一个字符串,用 数字×字符串对应的数值 思路: 用map对应数值,要注意的是字符串为P或者N的时候,不计入结果 代码: #include<iostream> ...
- Lex与Yacc学习(二)之第一个Lex程序
用lex识别单词 构建一个识别不同类型英语单词的简单程序.先识别词性(名词,动词等),然后再扩展到处理符合简单英语语法的多个单词的句子. 先列出要识别的一组动词: is am are w ...
- windows10系统下安装keras框架以theano为后端并配置gpu加速
在安装之前,请确保你的显卡是NVIDIA的,并且是以下型号,否则不能进行gpu加速,右键我的电脑--管理--设备管理器--显示适配器.另外如果你的电脑是windows7,安装教程也是一样的,不过根据k ...
- bat 获取命令执行后的多个返回值,并取最后一个
最近在使用bat,遇到了这样的问题,获取adb shell cat命令之后的所有返回值,查了很长时间,才找到,现分享给大家. 举例如下: @for /f "tokens=*" %% ...
- js根据银行卡号判断属于哪个银行,并返回银行缩写及银行卡类型
在做绑定银行卡,输入银行卡的时候,产品有这么一个需求,需要用户输入银行卡号的时候,显示对应的银行卡名称及简称.于是苦苦寻觅,终于找到了支付宝的开放API,银行卡校验接口 https://ccdca ...
- vs进行C#编程中常用的几个快捷键
(1)输入svm然后按Tab键会生成Main函数: (2)Ctrl +k+s 三个键一起按,会调出代码段:选中多行后,然后按以上三个快捷键,输入需要使用的代码段,按下Tab,代码段会自动包括选中代码. ...
- Spring注解@Component、@Repository、@Service、@Controller
@Service用于标注业务层组件 @Controller用于标注控制层组件(如struts中的action) @Repository用于标注数据访问组件,即DAO组件 @Component泛指组件, ...