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的数扔进线段树(线段树的下标就是数值 ...
随机推荐
- go map数据结构
map数据结构 key-value的数据结构,又叫字典或关联数组 声明: var map1 map[keytype]valuetype var a map[string]string var a ma ...
- Angular组件生命周期钩子
Angular会按以下顺序依次调用以下钩子(8个): ngOnChanges ngOnInit ngDoCheck ngAfterContentInit ngAfterContentChecked n ...
- Jenkins部署实战篇
Jenkins部署实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.持续集成理论 1>.开发写代码的演变过程 1.1>.一个开发单打独斗,撸代码,开发网站,自由 ...
- Hadoop生态圈-Oozie实战之逻辑调度执行多个Job
Hadoop生态圈-Oozie实战之逻辑调度执行多个Job 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 1>.启动hadoop集群 [root@yinzhengjie ha ...
- linux的防火墙
关闭防火墙: systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止firewall开 ...
- CentOS6.x下源码安装MySQL5.5
1. 更新yum源:http://www.cnblogs.com/vurtne-lu/p/7405931.html 2. 卸载原有的mysql数据库 [root@zabbix ~]# yum -y r ...
- Jquery 获取radio选中值
- 【BZOJ4827】【HNOI2017】礼物
强省HN弱省HA……(读作强省湖南弱省蛤 原题: 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每个手环上各有 n 个装饰物,并且每个 ...
- Android五种数据存储方式
android 五种数据存储 :SharePreferences.SQLite.Contert Provider.File.网络存储 Android系统提供了四种存储数据方式.分别为:SharePre ...
- Levmar 配置
Levmar配置 原文有些错误,在我的博客里已经改好了:http://blog.sina.com.cn/s/blog_45b747f70101he1t.html 如果6或者7自由度机器人的运动学逆解无 ...