BZOJ1112 - [POI2008]砖块Klo
原题链接
题意简述
给出一个n(n≤105)n(n \leq 10^5)个数的序列a(max{a}≤106)a(max\{a\}\leq10^6),每次给一个数+1/-1。求使得序列中存在连续k(k≤n)k(k \leq n)个相等的数至少要操作几次。
分析
题目实际上求的是|x1−h|+|x2−h|+...+|xk−h||x_1-h|+|x_2-h|+...+|x_k-h|的最小值,其中xx是aa的一个长度为kk的子串。
易知hh为序列xx的中位数时原式取得最小值,那我们的任务就是求区间中位数咯。
证明
记序列xx中小于hh的有c1c_1个,大于hh的有c2c_2个。
因为当hh增大Δh\Delta h,原式就增大Δh×c1−Δh×c2\Delta h \times c_1 - \Delta h \times c_2;
所以当c1<c2c_1时,hh越大原式越小;c1>c2c_1>c_2时,hh越大原式越大。
c1=c2c_1=c_2时原式取得最小值,此时hh为序列xx的中位数。因为max{a}≤106max\{a\}\leq10^6可以开数组,我们用树状数组实现。
维护xx中小于等于ii的数的个数cnt[i]cnt[i],小于等于ii的数的和sum[i]sum[i]。首先通过二分找出中位数h0h_0,则原式的最小值为h0×cnt[i]−sum[i]+h0×(k−cnt[i])×(Σxi−sum[i])h_0 \times cnt[i]-sum[i] + h_0 \times (k-cnt[i]) \times (\Sigma{x_i}-sum[i])
总时间复杂度约为 O(nlog2max{a})O(nlog^2max\{a\})。实现
开两个树状数组分别维护cnt[i],sum[i]cnt[i],sum[i]。
代码
//[POI2008]鐮栧潡Klo #include <cstdio> #include <algorithm> using namespace std; typedef long long lint; int const N=1e5+10; int const M=1e6+10; lint const INF=1LL<<62; int n,k,a[N]; int maxH; lint s[N]; lint tr[M],trs[M]; void add(int x,int f) {int x1=x;while(x1<=maxH) tr[x1]+=f,x1+=x1&(-x1);x1=x;while(x1<=maxH) trs[x1]+=f*x,x1+=x1&(-x1); } lint sum1(int x) {lint res=0;while(x>0) res+=tr[x],x-=x&(-x);return res; } lint sum2(int x) {lint res=0;while(x>0) res+=trs[x],x-=x&(-x);return res; } lint sol(int fr) {int L=0,R=maxH;while(L<R){int mid=(L+R)>>1;if(sum1(mid)<(k+1)/2) L=mid+1;else R=mid;}lint h=L,c1=sum1(h),c2=k-c1;lint s1=sum2(h),s2=s[fr+k-1]-s[fr-1]-s1;return (c1*h-s1)+(s2-c2*h); } int main() {scanf("%d%d",&n,&k);for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]++;for(int i=1;i<=n;i++) maxH=max(maxH,a[i]);for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];lint ans=INF;for(int i=1;i<=k;i++) add(a[i],1);ans=min(ans,sol(1));for(int i=2;i<=n-k+1;i++){add(a[i-1],-1); add(a[i+k-1],1);ans=min(ans,sol(i));}printf("%lld",ans);return 0; }
注意
要开long long
原数列中可能有0,先给全体+1s+1
BZOJ1112 - [POI2008]砖块Klo相关推荐
- bzoj1112[POI2008]砖块Klo*
bzoj1112[POI2008]砖块Klo 题意: N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:丢掉某柱砖的一块砖.给某柱加上一块砖,现在希望用最小次数的动作完成任务.N≤1 ...
- BZOJ1112[POI2008]砖块Klo——非旋转treap
题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...
- 【主席树】bzoj1112: [POI2008]砖块Klo
数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...
- BZOJ1112: [POI2008]砖块Klo(洛谷P3466)
平衡树 BZOJ题目传送门 洛谷题目传送门 动态维护中位数,平衡树上一发就好了. 代码: #include<cctype> #include<cstdio> #include& ...
- BZOJ1112: [POI2008]砖块Klo
Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次 ...
- bzoj1112: [POI2008]砖块Klo(splay)
题面在这里 做法 枚举每长度为 k k k 的段寻找中位数即可.splay维护. 代码 => 主要是想说这一点,由于计算的必要,相同的数不能合并到一个节点,否则之后调用 sum[ch[x][0] ...
- 1112: [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1245 Solved: 426 [Submit][Sta ...
- [POI2008]砖块Klo
1112: [POI2008]砖块Klo Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2910 Solved: 1026 [Submit][Stat ...
- [POI2008] 砖块Klo
洛谷 P3466 传送门 bzoj 1112 传送门 用treap维护一段长为k的区间即可. 先把1~k-1的都插入treap. 然后从k到n进行如下操作: 插入一个,计算,删除一个. 用到一个结论: ...
最新文章
- 一个基于Spring Boot的API、RESTful API项目骨架
- 线上经验总结:一台 Java 服务器可以跑多少个线程?
- 为什么大多Virtual Globe程序纵向旋转效率比较低
- 中國批准英特爾在東北投建晶片廠
- 开发辅助 | 阿里图标库iconfont入门使用
- ubuntu等linux系统给windows共享文件
- 基因组中的趣事(一):这个基因编码98种转录本
- 持续集成部署Jenkins工作笔记0013---配置远程触发构建的TOKEN值
- 分裂对象模型和TclCL(2)
- Cookie的过期时间设置
- 统计系统所有进程总共占用多少内存
- mysql数据库原理设计与应用在线pdf_《数据库原理与应用》[51MB]PDF完整版下载-码农之家...
- elementui实现横向时间轴_element ui step组件在另一侧加时间轴显示
- 腾讯bugly android sdk镜像,Android 腾讯bugly接入记录教程
- 截止频率计算公式wc_已知低通滤波器的传递函数是G(s)=(G0*Wc)/(s+Wc),截止频率不超过2HZ,怎么求?...
- 最新史上最大数据泄露,名为“Collection #1”的7.73亿数据!
- ucenter用户中心头像修改,不使用自带方法,不使用flash 转
- Open3D-GUI系列教程(七)打包应用程序
- 什么是session
- OpenCV3 和 Qt5 计算机视觉 学习笔记 - 图像转换