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

Solution

  妈丫BZOJ3224的$treap$调不出来只好另做一道$treap$简单题练手了。

  欸这道题还能用树状数组做么?本蒟蒻不会丫。

  这道题很容易想到,对于每一个区间,将区间内所有数改成该区间的中位数时开销最小。

  找中位数就是找第$(k+1)/2$的数$mid$嘛,于是一个$treap$的做法就诞生了。

  滑动窗口,每次保留$k$个数,求出比$mid$小的所有数的和$sum1$以及比$mid$大的所有数的和$sum2$

  答案就是$(sum1-(比mid小的数的个数)*mid)+((比mid大的数的个数)*mid-sum2)$

  欸好像可以化简,可以化简成$sum2-sum1$,$k$是偶数时多减一个$mid$

  普通$treap$,记一个$siz$和一个$sum$即可。

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct treap
{
int l, r, siz, val, pri;
ll key, sum;
}a[];
int root, ptot, h[];
ll sum1, sum2; void push_up(int k)
{
a[k].siz = a[a[k].l].siz + a[a[k].r].siz + a[k].val;
a[k].sum = a[a[k].l].sum + a[a[k].r].sum + a[k].key * a[k].val;
} void lturn(int &k)
{
int tmp = a[k].r;
a[k].r = a[tmp].l, a[tmp].l = k;
a[tmp].siz = a[k].siz, a[tmp].sum = a[k].sum;
push_up(k), k = tmp;
} void rturn(int &k)
{
int tmp = a[k].l;
a[k].l = a[tmp].r, a[tmp].r = k;
a[tmp].siz = a[k].siz, a[tmp].sum = a[k].sum;
push_up(k), k = tmp;
} void insert(int &k, int x)
{
if(!k)
{
k = ++ptot, a[k].siz = a[k].val = ;
a[k].sum = a[k].key = x, a[k].pri = rand();
return;
}
a[k].siz++, a[k].sum += x;
if(x == a[k].key) a[k].val++;
else if(x < a[k].key)
{
insert(a[k].l, x);
if(a[k].pri < a[a[k].l].pri) rturn(k);
}
else
{
insert(a[k].r, x);
if(a[k].pri < a[a[k].r].pri) lturn(k);
}
} void del(int &k, int x)
{
if(!k) return;
if(x == a[k].key)
if(a[k].val > ) a[k].val--, a[k].siz--, a[k].sum -= x;
else if(!(a[k].l * a[k].r)) k = a[k].l + a[k].r;
else if(a[a[k].l].pri < a[a[k].r].pri) lturn(k), del(k, x);
else rturn(k), del(k, x);
else if(x < a[k].key) a[k].siz--, a[k].sum -= x, del(a[k].l, x);
else a[k].siz--, a[k].sum -= x, del(a[k].r, x);
} int query_num(int k, int x)
{
if(!k) return ;
if(x <= a[a[k].l].siz)
{
sum2 += a[a[k].r].sum + a[k].key * a[k].val;
return query_num(a[k].l, x);
}
if(x <= a[a[k].l].siz + a[k].val)
{
sum1 += a[a[k].l].sum + (x - a[a[k].l].siz - ) * a[k].key;
sum2 += a[a[k].r].sum + (a[a[k].l].siz + a[k].val - x) * a[k].key;
return a[k].key;
}
sum1 += a[a[k].l].sum + a[k].key * a[k].val;
return query_num(a[k].r, x - a[a[k].l].siz - a[k].val);
} int main()
{
int n, k, mid;
ll ans = 100000000000000LL;
cin >> n >> k, srand(n);
for(int i = ; i <= n; i++)
cin >> h[i];
for(int i = ; i <= k; i++)
insert(root, h[i]);
for(int i = k + ; i <= n + ; i++)
{
sum1 = sum2 = ;
mid = query_num(root, (k + ) >> );
ans = min(ans, sum2 - sum1 - !(k & ) * mid);
insert(root, h[i]), del(root, h[i - k]);
}
cout << ans << endl;
return ;
}

[BZOJ1112] [POI2008] 砖块Klo (treap)的更多相关文章

  1. [BZOJ1112][POI2008]砖块Klo

    [BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...

  2. 【BZOJ1112】[POI2008]砖块Klo Treap

    [BZOJ1112][POI2008]砖块Klo Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出 ...

  3. [Bzoj1112][POI2008]砖块Klo(splay)

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2353  Solved: 831[Submit][Statu ...

  4. BZOJ1112[POI2008]砖块Klo——非旋转treap

    题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...

  5. 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo

    枚举长度为m的所有段,尝试用中位数更新答案. 所以需要数据结构,支持查询k大,以及大于/小于 k大值 的数的和. 平衡树.权值线段树.权值分块什么的随便呢. #include<cstdio> ...

  6. 【主席树】bzoj1112: [POI2008]砖块Klo

    数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...

  7. BZOJ 1112: [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1736  Solved: 606[Submit][Statu ...

  8. 1112: [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1245  Solved: 426[Submit][Statu ...

  9. [bzoj1112][POI2008]砖块Klo_非旋转Treap

    砖块Klo bzoj-1112 POI-2008 题目大意:$N$柱砖,希望有连续$K$柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖 ...

随机推荐

  1. Linux-安装FFmpeg

    FFmpeg官网:http://www.ffmpeg.org 官网介绍 FFmpeg is the leading multimedia framework, able to decode, enco ...

  2. 一个 rsync同步文件脚本

    #/bin/bash cd /root/phone echo "update guanwang phone version" git pull ]; then echo " ...

  3. css3渐变 transition使用方法

    <style> div{ width:300px; height:300px; background:#89F; margin:100px auto; transition:width 1 ...

  4. CSS中可以继承和不可继承的常见属性

    一.无继承性的属性 1.display:规定元素应该生成的框的类型 2.文本属性: vertical-align:垂直文本对齐 text-decoration:规定添加到文本的装饰 text-shad ...

  5. [记录]Zabbix3.4配置监控Oracle12c的存活状态和表空间使用率

    Zabbix3.4配置监控Oracle的存活状态和表空间使用率 1.安装zabbix3.4 agent: # rpm -ivh http://repo.zabbix.com/zabbix/3.4/rh ...

  6. 2015年百度实习生前端笔试题上海卷a

    1.写出javascript运行结果:alert(‘5’+5); 结果:’55’ 2.写出javascript运行结果:for(var i=0; i<10; i++){} alert(i); 结 ...

  7. [翻译] 编写高性能 .NET 代码--第二章 GC -- 减少分配率, 最重要的规则,缩短对象的生命周期,减少对象层次的深度,减少对象之间的引用,避免钉住对象(Pinning)

    减少分配率 这个几乎不用解释,减少了内存的使用量,自然就减少GC回收时的压力,同时降低了内存碎片与CPU的使用量.你可以用一些方法来达到这一目的,但它可能会与其它设计相冲突. 你需要在设计对象时仔细检 ...

  8. NumPy学习_00 ndarray的创建

    1.使用array()函数创建数组 参数可以为:单层或嵌套列表:嵌套元组或元组列表:元组或列表组成的列表 # 导入numpy库 import numpy as np # 由单层列表创建 a = np. ...

  9. UVA - 10285 Longest Run on a Snowboard (线性DP)

    思路:d[x][y]表示以(x, y)作为起点能得到的最长递减序列,转移方程d[x][y] = max(d[px][py] + 1),此处(px, py)是它的相邻位置并且该位置的值小于(x, y)处 ...

  10. hibernate框架基础描述

    在hibernate中,他通过配置文件(hibernate,cfg.xml)和映射文件(...hbm.xml)把对象或PO(持久化对象)映射到数据库中表,然后通过操作持久化对象,对数据库进行CRUD. ...