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的数扔进线段树(线段树的下标就是数值 ...
随机推荐
- eclipse卸载自带maven
1.在eclipse的安装目录下,找到 features和plugins文件夹,删除这两个文件夹下maven对应的jar和文件夹(windows用户建议用如下搜索:*maven*和*m2e*) 2 ...
- Ansible拷贝文件遇到的问题
ansible报错Aborting, target uses selinux but python bindings (libselinux-python) aren't installed 报错内容 ...
- Centos7更改yum镜像源
1. 备份本地yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak 2.获取阿里yum源配置文 ...
- JAVA求解全排列
一,问题描述 给定一个字符串,求出该字符串的全排列. 比如:"abc"的全排列是:abc.acb.bac.bca.cab.cba 二,实现思路 采用递归的方式求解.每次先选定一个字 ...
- 如何创建带有大纲和书签的交互式web报表
交互式报表允许用户与之交互.例如,报表可以包含超链接.书签和大纲.通过点击大纲部分的标题,你可以将书签导航到报表中的所需位置.这样的报表经常用在产品目录中.(查看更多web报表教程) 让我们为Web创 ...
- 22. SpringBoot 集成 Mybatis
1. 引入Mybatis的maven 依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> < ...
- writen.c
#include <unistd.h> #include <errno.h> ssize_t writen(int fd, const void *vptr, size_t n ...
- FineReport: 清空(重置)条件reset()
在使用控件时,有时我们希望能够快捷的重置控件的内容,或者重置所有控件的内容,效果如下图所示: 1.给需要重置的控件设置控件名 2.给重置按钮设置点击事件 3.点击事件中加入javascript代码 只 ...
- css命名规范: BEM 的命名法
整理自:前端早读课[第1183期]这些 CSS 命名规范,将省下你大把调试时间 试图解决 3 类问题: 仅从名字就能知道一个 CSS 选择器具体做什么 从名字能大致清楚一个选择器可以在哪里使用 从 C ...
- A - 最大子矩阵 HYSBZ - 1084 (DP)
题目链接:https://cn.vjudge.net/contest/281963#problem/A 题目大意:中文题目 具体思路:观察到m<=2,所以我们可以对两种情况进行单独讨论,当m== ...