BZOJ1112: [POI2008]砖块Klo Treap

来源:互联网 发布:vue.js和angularjs区别 编辑:程序博客网 时间:2024/04/28 16:49

BZOJ 1112: [POI2008]砖块Klo

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1701  Solved: 597
[Submit][Status][Discuss]

题解:
对于一个长度为K的区间,把这个区间内的砖块的高度都变成中位数是最优的。
维护一个平衡树:保持只有K个节点,支持插入删除元素,同时维护子树节点个数、子树权值和。
每次在树中查询第K/2大元素,同时计算权值比其大和权值比其小的所有节点的权值和
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define LL long longconst LL N=100005;const LL inf=1000000000000LL;int n,K,a[N],root;LL sum[N],w[N],v[N],ans=inf,now,tmp;int siz[N],ls[N],rs[N],rnd[N];void Pushup(LL x){siz[x]=siz[ls[x]]+siz[rs[x]]+w[x];sum[x]=sum[ls[x]]+sum[rs[x]]+w[x]*v[x];}void lx(int &x){int t=rs[x];rs[x]=ls[t],ls[t]=x;Pushup(x),Pushup(t);x=t;}void rx(int &x){int t=ls[x];ls[x]=rs[t],rs[t]=x;Pushup(x),Pushup(t);x=t;}int cnt;void Ins(int &x,int p){if(!x){x=++cnt,v[x]=p,sum[x]=p,w[x]=1,siz[x]=1,rnd[x]=rand();return;}if(v[x]==p) w[x]++;else if(p<v[x]){Ins(ls[x],p);if(rnd[ls[x]]>rnd[x]) rx(x);}else {Ins(rs[x],p);if(rnd[rs[x]]>rnd[x]) lx(x);}Pushup(x);}void Del(int &x,int p){if(v[x]==p)    {        if(w[x]>1) w[x]--;        else if(ls[x]*rs[x]==0) x=ls[x]+rs[x];        else if(rnd[ls[x]]<rnd[rs[x]]) lx(x),Del(x,p);        else rx(x),Del(x,p); } else if(p<v[x]) Del(ls[x],p); else Del(rs[x],p); Pushup(x);}void find(int x,int k){if(k<=siz[ls[x]]){now+=sum[x]-sum[ls[x]];find(ls[x],k);}else if(k<=siz[ls[x]]+w[x]){        now+=sum[rs[x]]+(siz[ls[x]]+w[x]-k)*v[x];now-=sum[ls[x]]+(k-siz[ls[x]])*v[x];tmp=v[x];return;}else{now-=sum[x]-sum[rs[x]];find(rs[x],k-(siz[x]-siz[rs[x]]));}}LL Query(){int pos=(K+1)>>1;now=0;find(root,pos);return (pos*2-K)*tmp+now;}int main(){scanf("%d%d",&n,&K);for(int i=1;i<=n;i++) scanf("%d",&a[i]);int j=1;for(int i=1;j<=n;i++){while(j<=n&&j<=i+K-1) Ins(root,a[j]),j++;ans=min(ans,Query());Del(root,a[i]);}printf("%lld",ans);}


Description

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

Input

第一行给出N,K. (1 ≤ k ≤ n ≤ 100000), 下面N行,每行代表这柱砖的高度.0 ≤ hi ≤ 1000000

Output

最小的动作次数

Sample Input

5 3
3
9
2
3
1

Sample Output

2

HINT

原题还要求输出结束状态时,每柱砖的高度.本题略去.

Source

[Submit][Status][Discuss]
0 0
原创粉丝点击