bzoj 1112: [POI2008]砖块Klo treap
来源:互联网 发布:excel 销售数据分析 编辑:程序博客网 时间:2024/04/18 15:20
题意
给出n个数,每次操作可以让一个数+1或-1,求连续的m个数,使得他们变成相同的数的操作数最少。
n,m<=100000
分析
假设现在给出m个数,要想使得他们变成相同的数的操作数最少,显然要让他们都变成这个m个数的中位数。
知道了这个后我们就可以用一棵treap来暴力这个m个值,然后每次查找中位数即可。
第一次用c++写treap,感觉好虚啊,顺便去借鉴了一波黄学长的删除操作。话说黄学长的代码真心简洁明了啊%%%
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define N 100005#define ll long longusing namespace std;int n,m,a[N],size,tot,root;ll sum,ans;struct tree{int size,val,in,l,r,k;ll s;}t[N];void updata(int x){ t[x].size=t[t[x].l].size+t[t[x].r].size+t[x].in; t[x].s=t[t[x].l].s+t[t[x].r].s+(ll)t[x].in*t[x].val;}void rttl(int &x){ int y=t[x].r; t[x].r=t[y].l; t[y].l=x; updata(x); updata(y); x=y;}void rttr(int &x){ int y=t[x].l; t[x].l=t[y].r; t[y].r=x; updata(x); updata(y); x=y;}void ins(int &x,int val){ if (!x) { x=++tot; t[x].val=t[x].s=val;t[x].size=t[x].in=1;t[x].k=rand(); return; } t[x].s+=val;t[x].size++; if (t[x].val==val) { t[x].in++; return; } if (val<t[x].val) { ins(t[x].l,val); if (t[t[x].l].k<t[x].k) rttr(x); }else { ins(t[x].r,val); if (t[t[x].r].k<t[x].k) rttl(x); }}void del(int &x,int val){ if (!x) return; if (t[x].val==val) { if (t[x].in>1) { t[x].in--;t[x].size--;t[x].s-=val;return; } else if (t[x].l*t[x].r==0) { x=t[x].l+t[x].r;return; } else if (t[t[x].l].k<t[t[x].r].k) { rttr(x);del(t[x].r,val); } else { rttl(x);del(t[x].l,val); } } else if (val<t[x].val) del(t[x].l,val); else del(t[x].r,val); updata(x);}int find(int x,int y){ if (t[t[x].l].size+1<=y&&t[t[x].l].size+t[x].in>=y) { sum+=t[t[x].l].s;size+=t[t[x].l].size; return t[x].val; } if (t[t[x].l].size+t[x].in<y) { sum+=t[t[x].l].s+(ll)t[x].val*t[x].in;size+=t[t[x].l].size+t[x].in; y-=t[t[x].l].size+t[x].in; return find(t[x].r,y); }else { return find(t[x].l,y); }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); t[0].k=1e7; for (int i=1;i<=m;i++) ins(root,a[i]); ll ans=1e17; sum=size=0; int x=find(root,(1+m)/2); ans=min(ans,(ll)x*size-sum+t[root].s-sum-(ll)x*(m-size)); for (int i=m+1;i<=n;i++) { del(root,a[i-m]); ins(root,a[i]); sum=size=0; int x=find(root,(1+m)/2); ans=min(ans,(ll)x*size-sum+t[root].s-sum-(ll)x*(m-size)); } printf("%lld",ans); return 0;}
0 0
- BZOJ 1112 POI2008 砖块Klo Treap
- BZOJ 1112 [POI2008]砖块Klo Treap
- bzoj 1112: [POI2008]砖块Klo treap
- 【BZOJ 1112】Poi2008砖块Klo treap
- BZOJ 1112: [POI2008]砖块Klo treap
- BZOJ 1112 [POI2008]砖块Klo Treap
- 【BZOJ 1112】 [POI2008]砖块Klo
- bzoj 1112 [POI2008]砖块Klo
- BZOJ1112: [POI2008]砖块Klo Treap
- bzoj 1112: [POI2008]砖块Klo(splay)
- 【BZOJ】1112 [POI2008]砖块Klo 平衡树
- 1112: [POI2008]砖块Klo
- 1112: [POI2008]砖块Klo
- BZOJ 1112: [POI2008]砖块Klo 线段树维护区间中位数
- BZOJ 1112: [POI2008]砖块Klo 平衡树,思维,枚举
- 【BZOJ】【P1112】【POI2008】【砖块Klo】【题解】【map】
- bzoj-1112 砖块Klo
- 1112: [POI2008]砖块Klo Splay+中位数
- acm99乘法表
- [2016/12/7]我要用到的perl知识
- sed 之 & 符号
- numpy函数学习
- 设计模式——简单工厂模式
- bzoj 1112: [POI2008]砖块Klo treap
- axis
- 润和面试题:开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
- 理解 ReadDirectoryChangesW
- 第一行代码第一章笔记
- bzoj2563 阿狸和桃子的游戏
- ButterKnife
- A robust fuzzy local information C-means clustering algorithm的Matlab实现
- 使用FDICreate、FDICopy分离cab包