【主席树】bzoj1112: [POI2008]砖块Klo
数据结构划一下水
Description
N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任务.
Input
第一行给出N,K. (1 ≤ k ≤ n ≤ 100000), 下面N行,每行代表这柱砖的高度.0 ≤ hi ≤ 1000000
Output
最小的动作次数
题目大意
有一个非负的数列,可以±1修改高度,求最小代价使得连续k个高度相同
题目分析
对于一个区间的答案,就相当于把所有数都放在数轴上,再求一个数使得它到所有数的总和最小。那么最优就等于是求一个区间的中位数。
于是问题相当于一个支持 求中位数;求比中位数小/大的数个数;求比中位数小/大的数总和 的数据结构。这个问题可以用主席树在$logn$内完成。
注意 printf(calc(),a,b) ,如果在calc()中改变了a,b,输出的a,b将会是改变之前的值。
#include<bits/stdc++.h>
typedef long long ll;
const int maxn = ;
const int maxNode = ; struct node
{
int val,l,r;
ll sum;
}a[maxNode];
ll ans,lsum,rsum,lcnt,rcnt;
int n,k;
int rt[maxn],w[maxn],cnt[maxn],tot; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void build(int &rt, int l, int r)
{
rt = ++tot;
if (l==r) return;
int mid = (l+r)>>;
build(a[rt].l, l, mid);
build(a[rt].r, mid+, r);
}
void update(int pre, int &rt, int l, int r, int c)
{
rt = ++tot, a[rt] = a[pre], ++a[rt].val, a[rt].sum += cnt[c];
if (l==r) return;
int mid = (l+r)>>;
if (c <= mid) update(a[pre].l, a[rt].l, l, mid, c);
else update(a[pre].r, a[rt].r, mid+, r, c);
}
int query(int pre, int rt, int l, int r, int k)
{
if (l==r) return l;
int val = a[a[rt].l].val-a[a[pre].l].val, mid = (l+r)>>;
if (val >= k){
lcnt -= a[a[rt].r].val-a[a[pre].r].val;
lsum -= a[a[rt].r].sum-a[a[pre].r].sum;
return query(a[pre].l, a[rt].l, l, mid, k);
}
rcnt -= a[a[rt].l].val-a[a[pre].l].val;
rsum -= a[a[rt].l].sum-a[a[pre].l].sum;
return query(a[pre].r, a[rt].r, mid+, r, k-val);
}
int main()
{
n = read(), k = read(), ans = 1ll<<;
for (int i=; i<=n; i++) w[i] = cnt[i] = read();
std::sort(cnt+, cnt+n+);
cnt[] = std::unique(cnt+, cnt+n+)-cnt-;
build(rt[], , cnt[]);
for (int i=; i<=n; i++)
{
w[i] = std::lower_bound(cnt+, cnt+cnt[]+, w[i])-cnt;
update(rt[i-], rt[i], , cnt[], w[i]);
}
for (int r=k; r<=n; r++)
{
int l = r-k;
lcnt = rcnt = a[rt[r]].val-a[rt[l]].val, lsum = rsum = a[rt[r]].sum-a[rt[l]].sum;
int tmp = cnt[query(rt[l], rt[r], , cnt[], (k+)>>)];
ans = std::min(ans, 1ll*tmp*(lcnt-rcnt)-lsum+rsum);
}
printf("%lld\n",ans);
return ;
}
END
【主席树】bzoj1112: [POI2008]砖块Klo的更多相关文章
- [BZOJ1112][POI2008]砖块Klo
[BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...
- [Bzoj1112][POI2008]砖块Klo(splay)
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2353 Solved: 831[Submit][Statu ...
- [BZOJ1112] [POI2008] 砖块Klo (treap)
Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次 ...
- 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo
枚举长度为m的所有段,尝试用中位数更新答案. 所以需要数据结构,支持查询k大,以及大于/小于 k大值 的数的和. 平衡树.权值线段树.权值分块什么的随便呢. #include<cstdio> ...
- BZOJ1112[POI2008]砖块Klo——非旋转treap
题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...
- 【BZOJ1112】[POI2008]砖块Klo Treap
[BZOJ1112][POI2008]砖块Klo Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出 ...
- BZOJ 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1736 Solved: 606[Submit][Statu ...
- 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1245 Solved: 426[Submit][Statu ...
- BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1112 [题目大意] 给出一个数列,对于一个操作,你可以对一个数+1,或者一个数-1, ...
随机推荐
- Docker学习:Docker安装和基本使用
Docker Docek是一种容器技术.容器是一种轻量级.可移植.自打包的软件技术,使应用程序可以在几乎任何地方以相同的方式运行. 使用者可以在笔记本上创建并测试好的容器,无需任何修改就能够在生产系统 ...
- NSPhotoLibraryAddUsageDescription解决办法
图片并保存到本地的功能,一点发现闪退了.发现 Xcode 报以下错误: The app's Info.plist must contain an NSPhotoLibraryAddUsageDescr ...
- 利用Hough变换识别图像中的直线
引入 近期看到2015年数学建模A题太阳影子定位中的第四问,需要根据附件中视频里的直杆的太阳影子的变化确定拍摄地点.其实确定拍摄地点这个问题并不是十分困难,因为有前三问的铺垫,我们已经得出了太阳影子长 ...
- 1e9个兵临城下(容斥原理)
链接:https://ac.nowcoder.com/acm/contest/321/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...
- 部署到CentOS Net Core
Net Core部署到CentOS 本文基于初次或再次尝试部署.Net Core应用到Linux服务器上,我尝试后自我总结的经验一个简单的Demo,尝试部署在Linux服务器上和跨服务器访问数据库. ...
- JS正则改变字符之间文字
var reg = /([[^[]*])/g; html = html.replace(reg, "<span class=\"bold\">$1</s ...
- JAVA基础之转换流和缓冲流
个人理解: 在理解的字符流和字节流的区别后.要是想读取指定的编码格式的文件时,特别是不是默认的格式时,就需要转换流了,需要注意的是字符流是需要清除缓冲区的:当需要快速的进行读取时,则需要缓冲流.存在即 ...
- 一、单例模式(Singleton)
单例模式最初的定义出现于<设计模式>(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点.” 特点:一是某个类只能有一个实例: 二是它必须自行创建这个实例: ...
- 判断浏览器是pc端还是移动端
var browser = { versions: function() { var u = navigator.userAgent, app = navigator.appVersion; retu ...
- 真正的S2b其实是S2b2c
本文转自阿里参谋长曾鸣:真正的S2b其实是S2b2c! 在<在未来五年,S2b是最有可能领先的商业模式>这篇文章发表之后,曾鸣书院收到了非常多的反馈,看到很多实践和思考. 在这篇文章中,曾 ...