【bzoj1112】【poi2008】【砖块】【treap】
来源:互联网 发布:财经杂志 知乎 编辑:程序博客网 时间:2024/04/28 23:41
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
3
9
2
3
1
Sample Output
2
题解:可以发现对于连续的k个,把它们都变成中位数最优.
所以用treap维护中位数即可.
因为要计算答案,所以treap里要维护权值和大小.
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#define N 100010using namespace std;int n,m,a[N],cnt,K,root;long long t1,t2,ans(12345678987654321LL),mid;struct use{int l,r,rd,sz,num;long long sm,v;}tr[N];void update(int k){ tr[k].sz=tr[tr[k].l].sz+tr[tr[k].r].sz+tr[k].num; tr[k].sm=tr[tr[k].l].sm+tr[tr[k].r].sm+tr[k].v*tr[k].num;}void lturn(int &k){ int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k; update(k);update(t);k=t;}void rturn(int &k){ int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k; update(k);update(t);k=t;}void insert(int &k,long long v){ if (!k){ k=++cnt;tr[k].v=tr[k].sm=v;tr[k].sz=tr[k].num=1; tr[k].rd=rand();return; } //tr[k].sz++;tr[k].sm+=v; if (tr[k].v==v) tr[k].num++; else if (v<tr[k].v){ insert(tr[k].l,v); if (tr[tr[k].l].rd<tr[k].rd) rturn(k); } else{ insert(tr[k].r,v); if (tr[tr[k].r].rd<tr[k].rd) lturn(k); } update(k);}void del(int &k,long long v){ if (k==0) return; if (tr[k].v==v){ if (tr[k].num>1){tr[k].sm-=v;tr[k].num--;tr[k].sz--;return;} else{ if (tr[k].l*tr[k].r==0) k=tr[k].l+tr[k].r; else if (tr[tr[k].l].rd<tr[k].rd){rturn(k);del(k,v);} else{lturn(k);del(k,v);} } } else if (v<tr[k].v){del(tr[k].l,v);} else {del(tr[k].r,v);} update(k);}void find(int k,int rk){ if (k==0) return; if (tr[tr[k].l].sz>=rk){ t2+=tr[k].v*tr[k].num+tr[tr[k].r].sm; find(tr[k].l,rk); } else if (tr[tr[k].l].sz+tr[k].num>=rk){ t1+=tr[tr[k].l].sm+(rk-tr[tr[k].l].sz-1)*tr[k].v; t2+=tr[tr[k].r].sm+(tr[tr[k].l].sz+tr[k].num-rk)*tr[k].v;mid=tr[k].v; } else{ t1+=tr[tr[k].l].sm+tr[k].v*tr[k].num; find(tr[k].r,rk-tr[tr[k].l].sz-tr[k].num); }}void getans(){ t1=t2=0;int temp=(K+1)>>1; find(root,temp); long long sum=(temp-1)*mid-t1+t2-(K-temp)*mid; ans=min(ans,sum); }int main(){ scanf("%d%d",&n,&K); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=K;i++) insert(root,(long long)a[i]); getans(); for (int i=K+1;i<=n;i++){ del(root,a[i-K]); insert(root,a[i]);getans(); } cout<<ans<<endl;}
0 0
- 【bzoj1112】【poi2008】【砖块】【treap】
- BZOJ1112: [POI2008]砖块Klo Treap
- bzoj1112 [POI2008]砖块Klo
- bzoj1112【poi2008】砖块klo
- 【POI2008】【BZOJ1112】砖块Klo
- BZOJ1112: [POI2008]砖块Klo
- bzoj1112: [POI2008]砖块Klo
- 【bzoj1112】[POI2008]砖块Klo
- [bzoj1112][POI2008]砖块Klo
- [BZOJ1112]砖块klo Treap
- Bzoj1112:[POI2008]砖块Klo:splay
- 【BZOJ1112】[POI2008]砖块Klo【Splay】
- [BZOJ1112][POI2008]砖块Klo(splay)
- bzoj1112 POI2008 砖块Klo 树状数组
- [主席树] BZOJ1112: [POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)
- BZOJ 1112 POI2008 砖块Klo Treap
- BZOJ 1112 [POI2008]砖块Klo Treap
- Android开发相关的Blog推荐
- Manhaten Distance
- ASP.Net MVC中 Echarts简单Demo
- sqlserver2008收缩日志
- Qt Model/View 构架
- 【bzoj1112】【poi2008】【砖块】【treap】
- Android Wear Preview Program Overview
- Android中的进程和线程
- spring schedule定时任务(一):注解的方式
- 标志寄存器
- GDB 调试程序
- 2016半年过去了,习总跟您谈谈您对中国经济观点,下半年将会如何?
- wear api overview
- OpenWrt配置篇