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的数扔进线段树(线段树的下标就是数值 ...
随机推荐
- 多目标遗传算法 ------ NSGA-II (部分源码解析)辅助变量 双链表操作 list.c
/* A custom doubly linked list implemenation */ # include <stdio.h> # include <stdlib.h> ...
- vue 中this指向遇到的坑
vue中的this指向问题 如果方法中没有使用箭头函数,记得把this赋值给另一个变量再使用.
- IoC之Spring.Net在Mvc项目中的使用
MVC中使用Spring.net 前面学习了使用Autofac来实现控制反转,这里简单记录Spring.Net实现IoC和DI的步骤 第一步:安装如下Nuget包 (Spring.Web.Mvc) i ...
- LaTeX简历模板
%# -*- coding:utf-8 -*- %% start of file `template_en.tex'. %% Copyright 2006-1008 Xavier Danaux (xd ...
- java中常用的包及作用
1. java.awt:提供了绘图和图像类,主要用于编写GUI程序,包括按钮.标签等常用组件以及相应的事件类. 2. java.lang:java的语言包,是核心包,默认导入到用户程序,包中有obje ...
- memcache的下载与安装
memcache的安装: 建议安装1.4.4版本 Windows 下安装 Memcached 官网上并未提供 Memcached 的 Windows 平台安装包,我们可以使用以下链接来下载,你需要根据 ...
- 用命令行发布android程序
在开发android程序的过程中,我们使用ant debug和ant installd这两个命令就够了,不涉及到APK的签名. 但是在正式发布我们的Android程序时,需要对APK签名.ant re ...
- Elastic Job入门(2) - 使用
运维平台 elastic-job-lite-console-${version}.tar.gz可通过mvn install编译获取,下载源码,进入console目录,执行: mvn clean ins ...
- XML之Well-Formed文档规则
由于课程原因,近日粗略学习XML,载以博客是为担心忘记,以供日后复习之用. XML标准中明确规定了XML文件应当遵守的规则,大致上分成基本规则和DTD(Document Type Definition ...
- POJ3436 ACM Computer Factory【EK算法】
题意: 每个电脑需要P个组成部分,现有N的机器,每个机器都可以对电脑进行加工,不过加工的前提是某些部分已经存在,加工后会增加某些部分.且在单位时间内,每个机器的加工都有一个最大加工容量,求能得到的最大 ...