【bzoj 1112】砖块Klo(权值线段树)
2018-02-28 18:27
344 查看
传送门biu~
对于连续的k柱,如果想要让它们变成一样高的,显然把它们都转化成这k柱高度的中位数可以使操作次数最小。在权值线段树上查询中位数并计算。
对于连续的k柱,如果想要让它们变成一样高的,显然把它们都转化成这k柱高度的中位数可以使操作次数最小。在权值线段树上查询中位数并计算。
#include<bits/stdc++.h> using namespace std; const int inf=1000000; int n,k,a[100005]; long long ans=1LL<<60; struct Node{ Node *ch[2]; int siz; long long sum; Node(); inline void maintain(){ siz=ch[0]->siz+ch[1]->siz; sum=ch[0]->sum+ch[1]->sum; } }*null=new Node,*root=null; Node :: Node(){ ch[0]=ch[1]=null; siz=sum=0; } void add(Node *&o,int l,int r,int x,int v){ if(o==null) o=new Node; if(l==r){ o->siz+=v; o->sum+=x; return; } int mid=l+r>>1; if(abs(x)<=mid) add(o->ch[0],l,mid,x,v); else add(o->ch[1],mid+1,r,x,v); o->maintain(); } int Kth(Node *o,int l,int r,int k){ if(l==r) return l; int mid=l+r>>1; if(o->ch[0]->siz>=k) return Kth(o->ch[0],l,mid,k); else return Kth(o->ch[1],mid+1,r,k-o->ch[0]->siz); } long long Query(Node *o,int l,int r,int p){ if(o==null) return 0; if(r<=p || l>p) return abs(o->sum-1ll*p*o->siz); int mid=l+r>>1; return Query(o->ch[0],l,mid,p)+Query(o->ch[1],mid+1,r,p); } int main(){ scanf("%d%d",&n,&k); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=n;++i){ add(root,0,inf,a[i],1); if(i-k>0) add(root,0,inf,-a[i-k],-1); if(i<k) continue; int p=Kth(root,0,inf,(k+1)/2); ans=min(ans,Query(root,0,inf,p)); } printf("%lld\n",ans); return 0; }
相关文章推荐
- BZOJ 1112: [POI2008]砖块Klo 线段树维护区间中位数
- 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo
- BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)
- BZOJ1112 - [POI2008]砖块Klo
- bzoj1112 [POI2008] 砖块Klo
- BZOJ 1112: [POI2008]砖块Klo
- BZOJ1112: [POI2008]砖块Klo
- BZOJ 1112: [POI2008]砖块Klo 平衡树,思维,枚举
- 【bzoj1112】[POI2008]砖块Klo
- 【BZOJ1112】[POI2008]砖块Klo【Splay】
- bzoj 1112: [POI2008]砖块Klo【对顶堆】
- 【BZOJ 1112】 [POI2008]砖块Klo
- bzoj-1112 砖块Klo
- [bzoj1112][POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo
- 【BZOJ】1112 [POI2008]砖块Klo 平衡树
- bzoj1112 [POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)
- [BZOJ1112][POI2008]砖块Klo(splay)
- 【BZOJ1112】[POI2008]砖块Klo Treap