bzoj 1112 poi 2008 砖块
这滞胀题调了两天了...
好愚蠢的错误啊...
其实这道题思维比较简单,就是利用treap进行维护(有人说线段树好写,表示treap真心很模板)
就是枚举所有长度为k的区间,查出中位数,计算代价即可。
(根据绝对值不等式的几何意义,中位数一定是最优解)
而维护长度为k的区间也很简单,就是首先把前k个扔到树上,然后每次把新来的插入,把最前面的一个删除即可
至于求中位数,简直就是基础操作嘛
关键在于...代价怎么算?
显然我们不能把所有数枚举出来挨个加减,这样会T飞的...
所以我们考虑直接在treap上维护,根据treap很重要的性质:左树<根<右树
那么我们对每个节点,维护一个子树权值和,这样就可以做到在查询中位数的同时查出小于中位数的数之和和大于中位数的数之和了
注意一个小细节,就是在查询的时候,要把重复出现的中位数分左右放到左右的和里,否则计算会有bug
剩下的就是模板了
不要像我一样,插点不修改树的大小,输出全是负数...
贴代码(巨丑)
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ls tree[rt].lson
#define rs tree[rt].rson
#define ll long long
using namespace std;
struct Treap
{
int lson;
int rson;
int huge;
int same;
ll val;
int rank;
ll sum;
}tree[];
int a[];
int tot=;
int n,k,mid;
ll s[];
int rot=;
inline int read()
{
int f=,x=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void update(int rt)
{
tree[rt].huge=tree[ls].huge+tree[rs].huge+tree[rt].same;
tree[rt].sum=(ll)tree[ls].sum+(ll)tree[rs].sum+(ll)tree[rt].same*(ll)tree[rt].val;
}
void lturn(int &rt)
{
int temp=rs;
rs=tree[rs].lson;
tree[temp].huge=tree[rt].huge;
tree[temp].sum=tree[rt].sum;
tree[temp].lson=rt;
update(rt);
rt=temp;
}
void rturn(int &rt)
{
int temp=ls;
ls=tree[ls].rson;
tree[temp].huge=tree[rt].huge;
tree[temp].rson=rt;
tree[temp].sum=tree[rt].sum;
update(rt);
rt=temp;
}
void ins(int &rt,ll v)
{
if(!rt)
{
rt=++tot;
tree[rt].huge=;
tree[rt].same=;
tree[rt].val=v;
tree[rt].rank=rand();
tree[rt].sum=v;
return;
}
tree[rt].sum+=v;
tree[rt].huge++;
if(tree[rt].val==v)
{
tree[rt].same++;
return;
}
if(tree[rt].val>v)
{
ins(ls,v);
if(tree[ls].rank<tree[rt].rank)
{
rturn(rt);
}
}else
{
ins(rs,v);
if(tree[rs].rank<tree[rt].rank)
{
lturn(rt);
}
}
}
void del(int &rt,ll v)
{
if(!rt)
{
return;
}
if(tree[rt].val==v)
{
if(tree[rt].same>)
{
tree[rt].huge--;
tree[rt].same--;
tree[rt].sum-=(ll)v;
return;
}else if(ls*rs==)
{
rt=ls+rs;
return;
}else
{
if(tree[ls].rank<tree[rs].rank)
{
rturn(rt);
del(rt,v);
}else
{
lturn(rt);
del(rt,v);
}
}
return;
}
tree[rt].huge--;
tree[rt].sum-=v;
if(tree[rt].val>v)
{
del(ls,v);
}else
{
del(rs,v);
}
update(rt);
}
ll Lsum,Rsum;
int tt;
int query_num(int rt,int v)
{
if(!rt)
{
return ;
}
if(tree[ls].huge>=v)
{
Rsum+=(ll)tree[rs].sum+(ll)tree[rt].same*(ll)tree[rt].val;
return query_num(ls,v);
}else if(tree[ls].huge+tree[rt].same<v)
{
Lsum+=(ll)tree[ls].sum+(ll)tree[rt].val*(ll)tree[rt].same;
return query_num(rs,v-tree[ls].huge-tree[rt].same);
}else
{
Lsum+=(ll)tree[ls].sum+(ll)(v-tree[ls].huge-)*(ll)tree[rt].val;
Rsum+=(ll)tree[rs].sum+(ll)(tree[ls].huge+tree[rt].same-v)*(ll)tree[rt].val;
return tree[rt].val;
}
}
int main()
{
n=read(),k=read();
mid=(k+)/;
for(int i=;i<=n;i++)
{
a[i]=read();
}
for(int i=;i<=k;i++)
{
ins(rot,a[i]);
}
int lret=,rret=k;
int v0=query_num(rot,mid);
int ret=v0;
ll co=(ll)(mid-)*(ll)v0-Lsum+Rsum-(ll)(k-mid)*(ll)v0;
for(int i=k+;i<=n;i++)
{
int st=i-k+;
del(rot,a[st-]);
ins(rot,a[i]);
tt=,Lsum=,Rsum=;
int v1=query_num(rot,mid);
ll temp=(ll)(mid-)*(ll)v1-Lsum+Rsum-(ll)(k-mid)*(ll)v1;
if(co>temp)
{
co=temp;
lret=st;
rret=i;
ret=v1;
}
}
printf("%lld\n",co);
for(int i=;i<=n;i++)
{
if(i<lret||i>rret)
{
printf("%d\n",a[i]);
}else
{
printf("%d\n",ret);
}
}
return ;
}
bzoj 1112 poi 2008 砖块的更多相关文章
- [BZOJ 1124][POI 2008] 枪战 Maf
1124: [POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 659 Solved: 259[Submit][Status ...
- [BZOJ 1112] [POI2008] 砖块Klo 【区间K大】
题目链接:BZOJ - 1112 题目分析 枚举每一个长度为k的连续区间,求出这个区间的最优答案,更新全局答案. 可以发现,这个区间的所有柱子最终都变成这k个数的中位数时最优,那么我们就需要查询这个区 ...
- [BZOJ 1013][JSOI 2008] 球形空间产生器sphere 题解(高斯消元)
[BZOJ 1013][JSOI 2008] 球形空间产生器sphere Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面 ...
- [POI 2008&洛谷P3467]PLA-Postering 题解(单调栈)
[POI 2008&洛谷P3467]PLA-Postering Description Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长 ...
- 从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流)
从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流) 题面 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运 ...
- BZOJ 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1736 Solved: 606[Submit][Statu ...
- BZOJ 1112: [POI2008]砖块Klo1112( BST )
枚举每个长度为k的区间, 然后用平衡树找中位数进行判断, 时间复杂度O(nlogn). 早上起来精神状态不太好...连平衡树都不太会写了...果断去看了会儿番然后就A了哈哈哈 ------------ ...
- [POI 2008][BZOJ 1132]Tro
这题我真是无能为力了 这题的做法还是挺简单的 枚举左下角的点做为原点,把其余点按极角排序 PS.是作为原点,如枚举到 k 时,对于所有 p[i] (包括p[k]) p[i]-=p[k] (此处为 ...
- 线段树 || BZOJ 1112: [POI2008]砖块Klo
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1112 题解: 希望有连续K柱的高度是一样的,就先把1~K的数扔进线段树(线段树的下标就是数值 ...
随机推荐
- P2422 良好的感觉
P2422 良好的感觉 给定一段序列, 其中元素 \(0 \leq a_{i} \leq 100000\) 定义一段子段 \([L, R]\) 的舒适值为 \(\min_{L \leq i \leq ...
- JavaSE学习总结(九)—— Java访问数据库(JDBC)
一.JDBC简介 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java ...
- Java中Jdom解析XML
JDOM与DOM类似,也是一组用于解析XML的API,它本身不是一个解析器,默认的它内置了Apache的Xerces解析器:JDOM与DOM不同的是,DOM是跨语言的一套API,Java世界中有很多D ...
- Linux记录-CentOS配置Docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...
- xshell访问Ubuntu16.04显示乱码(即使在xshell设置了utf8)解决方案
一开始问题是:(无法显示,也无法输入) 然后使用: locale -a 查看服务器安装的全部编码: (且服务器使用的 LANG=C) 只要用: 即可显示中文.也可以输入中文.
- windows上使用mkdocs搭建静态博客
windows上使用mkdocs搭建静态博客 之前尝试过用HEXO搭建静态博客,最近发现有个叫mkdocs的开源项目也是搭建静态博客的好选择,而且它支持markdown格式,下面简要介绍一下mkdoc ...
- JS知识整理之 Call&Apply方法
JavaScript中的函数也是对象,和其他JS对象一样也可以包含方法,其中Call和Apply就是其中比较重要的方法,可以用来间接的调用函数.这两个方法允许显式制定调用所需的this值,也就是说所有 ...
- position属性absolute与relative 的区别
连接:https://www.cnblogs.com/duyanli/p/3534005.html 每次要用到Position属性时,总要去搜索下,这两个属性值的区别:今天就直接复制网上的结果,以便以 ...
- Ubuntu16.04安装搜狗拼音输入法(中文输入法)
虽然网上有很多教程,但是我觉得我的很适合那些真正的小白... 1.下载文件 由于我要给多台电脑安装搜狗输入法,所以用的是文件夹安装,不是命令行安装. 打开官网http://pinyin.sogou.c ...
- CF448C Painting Fence (贪心分治)
题面 \(solution:\) 一道蛮水的分治题,但思想很不错(虽然我还是非常天真的以为是积木大赛原题,并且居然还有30分) 看到这个题目,根据贪心的一贯风格,我们肯定能想到将整个栅栏的下面某部分直 ...