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的数扔进线段树(线段树的下标就是数值 ...
随机推荐
- Harbor镜像清理
目录 清理UI中的镜像 清理镜像释放空间 docker镜像仓库中镜像的清理,一直是个比较麻烦的事情.尤其是在测试环境当中,每天都会有大量的构建.由此会产生大量的历史镜像,而这些镜像,大多数都没有用. ...
- TCP和UDP基本原理
TCP和UDP基本原理 传输层的主要任务就是建立应用程序间的端到端连接,并且为数据传输提供可靠或不可靠的通信服务,TCP/IP协议族的传输层协议主要包括TCP和UDP ,TCP是面向连接的可靠的传输层 ...
- Linux命令之ls
ls命令 用处:列出此目录下的文件和目录 用法:直接在终端中输入ls就好了 示例: 看到了吗,文件夹和文件都显示出来了哦 可是,电脑里面有时会有一些隐藏文件,我还想看到这些隐藏文件怎么办呢?加 -a ...
- Study 7 —— CSS美化背景和边框
图片透明度属性:opacity 背景图片重复属性:background-repeat背景图片位置属性:background-position background-postion:横坐标 纵坐标; b ...
- ext中grid根据数据不同显示不同样式
核心代码: var clsRender = function(value){ if (value == 'male') { return "<span style='color:red ...
- Keil5下载STM32库
1.http://www.keil.com/dd2 2.3.以STM32L051C8为例 下载即可.
- Dom4j工具类源码解析
话不多说,上源码: package com.changeyd.utils;import java.io.File;import java.io.FileNotFoundException;import ...
- JavaScript之Ajax(一)创建Ajax对象
// 支持浏览器的源码 function AjaxObject() { var AjaxRequest; // 缓存XHR对象便于 Ajax 使用 try { // Opera 8.0+, Firef ...
- POJ 1200 Crazy Search (哈希)
题目链接 Description Many people like to solve hard puzzles some of which may lead them to madness. One ...
- B. Light It Up
题目链接:http://codeforces.com/problemset/problem/1000/B 代码: #include<iostream> #include<cstrin ...