题意:

N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任务.你还要求输出结束状态时,每柱砖的高度


题解:
很显然,要让我们将这K个柱子变成一样高并且操作次数最少,就是求这K个数的中位数

所以我们需要用一种数据结构能够实现插入,删除,求第k大,它前面有多少个数,后面有多少个数。

然后根据这K个数和中位数就能计算出最少次数了

ans=min(∑i=lr∣ai−x∣)ans = min(\sum_{i=l}^{r}|a_i-x|)ans=min(i=l∑r​∣ai​−x∣)

找到中位数后就可以知道

ans=min(∑i=lmidx−ai+∑i=mid+1rai−x)ans = min(\sum_{i=l}^{mid}x-a_i+\sum_{i=mid+1}^{r}a_i-x)ans=min(i=l∑mid​x−ai​+i=mid+1∑r​ai​−x)

左边可以通过将中位数伸展到根节点,然后求出比该数小的和及比它大的数的和即可

szleft∗a[mid]−t[l].sum+t[r].sum−szright∗a[mid]sz_{left}*a[mid] - t[l].sum + t[r].sum - sz_{right}*a[mid]szleft​∗a[mid]−t[l].sum+t[r].sum−szright​∗a[mid]

这里我用的是Splay,当然fhq,zkw线段树,主席树都行。有思路就好做了,接下来就是码农时间了。


AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long LL;
const int MAXN = 1e5+10;
const int MOD = 998244353;
struct node{ int son[2],fa,cnt,sz,sum,val; }t[MAXN];
int root,tot,a[MAXN];
inline int id(int x){ return x==t[t[x].fa].son[1]; }
inline void pushup(int x){t[x].sz = t[t[x].son[0]].sz+t[t[x].son[1]].sz+t[x].cnt;t[x].sum = t[t[x].son[0]].sum + t[t[x].son[1]].sum+t[x].val*t[x].cnt;
}
inline void rotate(int x){int y=t[x].fa,z=t[y].fa,k=id(x);t[z].son[id(y)]=x; t[x].fa=z;t[y].son[k]=t[x].son[k^1]; t[t[x].son[k^1]].fa=y;t[x].son[k^1]=y; t[y].fa=x;pushup(y); pushup(x);
}
inline void splay(int x,int pos){while(t[x].fa!=pos){int y=t[x].fa,z=t[y].fa;if(z!=pos) id(x)==id(y) ? rotate(y):rotate(x);rotate(x);}if(!pos) root=x;
}
inline void update(int u,int fa,int x){t[u].cnt=t[u].sz=1;t[u].fa=fa; t[u].sum=t[u].val=x;
}
inline void Insert(int x){if(!root){root=++tot;update(root,0,x); return;}int u=root;while(1){t[u].sum += x; t[u].sz ++;if(t[u].val==x) { t[u].cnt++; splay(u,0); return; }int v = x>t[u].val;if(!t[u].son[v]){t[u].son[v]=++tot; update(t[u].son[v],u,x);u=t[u].son[v]; splay(u,0); return;}u=t[u].son[v];}
}
inline void del(int x){int u=root;while(t[u].val!=x) u=t[u].son[x>t[u].val];splay(u,0);t[u].cnt--; t[u].sz--; t[u].sum-=x;if(t[u].cnt) return;int nxt=t[u].son[1];while(nxt && t[nxt].son[0]) nxt=t[nxt].son[0];if(!nxt) { root=t[u].son[0]; t[root].fa=0; }else{splay(nxt,u);t[nxt].son[0]=t[u].son[0];t[t[u].son[0]].fa=nxt;t[root=nxt].fa=0;pushup(root);}
}
inline int kth(int x){int u=root;while(1){if(t[t[u].son[0]].sz>=x) u=t[u].son[0];else{if(t[t[u].son[0]].sz+1<=x && x<=t[t[u].son[0]].sz+t[u].cnt) return u;x -= t[t[u].son[0]].sz+t[u].cnt;u = t[u].son[1];}}
}
signed main(){#ifndef ONLINE_JUDGEfreopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGEint n,k; scanf("%lld%lld",&n,&k);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);for(int i=1;i<=k;i++) Insert(a[i]);int mid = (k+1)/2,ans = 1e18,l=0,r=0,tag=0;for(int i=k;i<=n;i++){int u=kth(mid);splay(u,0);int res = 0;res = t[t[u].son[0]].sz*t[u].val-t[t[u].son[0]].sum+t[t[u].son[1]].sum-t[t[u].son[1]].sz*t[u].val;if(res<ans){ ans=res; l=i-k+1; r=i; tag=t[u].val; }del(a[i-k+1]);if(i+1<=n) Insert(a[i+1]);}printf("%lld\n",ans);for(int i=1;i<=n;i++)if(i>=l && i<=r) printf("%lld\n",tag);else printf("%lld\n",a[i]);return 0;
}

P3466 [POI2008]KLO-Building blocks(Splay)相关推荐

  1. 解决Eclipse 启动后总是Building WorkSpace(sleeping)

    2019独角兽企业重金招聘Python工程师标准>>> 今天打开eclipse后eclipse总是在Building WorkSpace(sleeping),我的解决方案是,Proj ...

  2. fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)...

    题面: [模板]文艺平衡树(Splay) 题解:无 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<iostr ...

  3. 伸展树(Splay)

    伸展树(Splay) Splay 是一种二叉查找树,它通过不断将某个节点旋转到根节点,使得整棵树仍然满足二叉查找树的性质,并且保持平衡而不至于退化为链.它由 Daniel Sleator 和 Robe ...

  4. BZOJ 1503 郁闷的出纳员(splay)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 题意:给出一个数列(初始为空),给出一个最小值Min,当数列中的数字小于Min时自动 ...

  5. 平衡树(splay)学习笔记(详细,从入门到精(bao)通(ling))(持续更新)

    前言 在前几天军训站军姿的时候胡思乱想,突然明白了splay的本质 KMP学习笔记后又一篇字数上万的题解- 前置技能--二叉搜索树 首先来看一个最简单的问题: 你需要维护一个数据结构,资磁这些操作: ...

  6. 【BZOJ4864】【BeiJing 2017 Wc】神秘物质(Splay)

    Description 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天研究各种微观粒子.这 一天, 小诚刚从研究所得到了一块奇异的陨石样本, 便 ...

  7. Moodle插件开发——Blocks(版块)

    前提: 1)     基于Moodle3.0,要求Moodle版本高于2.0 2)     PHP编程基础:语言的了解和开发工具使用 有经验的开发人员和那些只是想程序员的参考文本应参阅附录A. 1.  ...

  8. bzoj1112: [POI2008]砖块Klo(splay)

    题面在这里 做法 枚举每长度为 k k k 的段寻找中位数即可.splay维护. 代码 => 主要是想说这一点,由于计算的必要,相同的数不能合并到一个节点,否则之后调用 sum[ch[x][0] ...

  9. P3391 【模板】文艺平衡树(Splay)

    Splay #include<cstdio> #include<algorithm> #include<iostream> using namespace std; ...

最新文章

  1. suse 安装oracle11,Suse11安装Oracle11gR2
  2. WebSocket实践
  3. MySQL 输入输出 XML
  4. 美图手机告别文,写得真好!
  5. centos7完全卸载mysql_Centos7 完全卸载mysql
  6. 解决 Evernote 印象笔记中代码语法高亮
  7. 精密测量和超精密测量
  8. TCP端口的十一种连接状态
  9. 一、FPGA Cyclone Ⅳ OV5640图像实时采集系统设计
  10. 微信公众号身份证OCR识别和验真|人证比对
  11. 【备忘】Google Android开发入门与实战 PDF 下载
  12. itss认证费用多少钱
  13. 面试官-你真的懂computed原理?(源码解读)
  14. 如何撰写本科毕业论文文献综述,这篇文章帮你全搞定
  15. A记录和CNAME记录——【网络】
  16. 今日芯声 | 嘘!你与谷歌语音助手的对话,可能已经泄露……
  17. 小米电视访问电脑共享文件夹
  18. 概率统计及其应用第三章知识总结_2020考研数学概率论与数理统计:各章节考试重点分析...
  19. java向匿名内部类传递参数
  20. 查杀计算机病毒的方法有利用,一种基于数据流的计算机病毒查杀方法专利_专利查询 - 天眼查...

热门文章

  1. 百度BI平台 BiPlatform windows安装问题随笔
  2. String was not recognized as a valid DateTime“ SQLITE解决
  3. 免费站群软件SEO—站掌门
  4. Android无障碍开发
  5. 【ASP.NET Web】项目实践—网上宠物店2:创建ASP.NET Web 网站项目、连接数据库
  6. 1+X证书Web前端开发规范手册
  7. 基于fpga的测温系统,verilog实现 代码程序,quartus直接打开使用
  8. 【openjudge】网线主管 二分查找
  9. 大数据Flink(四十五):​​​​​​扩展阅读 双流Join
  10. 前端小技巧:javascript 获取标签中的属性 对指定标签中的属性进行操作