【主席树】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, ...
随机推荐
- 图像像素灰度内插(Matlab实现)
常用的像素灰度内插法:最近邻元法.双线性内插法.三次内插法 %%像素灰度内插 factor = 0.75;%缩放比 u = 0.6;v = 0.7; itp1 = uint8(zeros(ceil(h ...
- SP14932 LCA - Lowest Common Ancestor
Description: 一棵树是一个简单无向图,图中任意两个节点仅被一条边连接,所有连通无环无向图都是一棵树.\(-Wikipedia\) 最近公共祖先(\(LCA\))是--(此处省去对\(LCA ...
- Ajax案例:异步加载商品分类信息
- $("body").animate({"scrollTop":top})无效的问题
问题 我在个人站点的左下角和右下角各自使用了如下代码来将页面滚动到顶部和底部: $("body").animate({scrollTop:0},800); $("body ...
- java模拟多线程
public class HTTPRequest implements Runnable { public void run() { //这里实现发送请求 } public static void ...
- 关于idea的快捷键提示
IntelliJ Idea 常用快捷键列表 Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Sh ...
- js 创建方法
贴个代码先: function O(user,pwd){ //use constructor this.user=user; this.pwd=pwd; this.get=get; return th ...
- [Java]ArrayList、LinkedList、Vector、Stack的比较
一.介绍 先回顾一下List的框架图 由图中的继承关系,可以知道,ArrayList.LinkedList.Vector.Stack都是List的四个实现类. AbstractList是一个抽象类,它 ...
- Mysql数据表的增删改查
---恢复内容开始--- Mysql数据表的增删改查 1.创建表 语法:CREATE TABLE 表名(字段1,字段2,字段3.......) CREATE TABLE `users` ( `us ...
- Spark Mllib里如何建立向量标签(图文详解)
不多说,直接上干货! 注意: val pos = LabeledPoint(1, vd) val neg = LabeledPoint(2, vs) 除了这两种建立向量标签.还可以从数据库中获取固定格 ...