【BZOJ】1112 [POI2008]砖块Klo 平衡树
来源:互联网 发布:淘宝逛网 编辑:程序博客网 时间:2024/04/20 10:44
题目传送门
今天一晚上就做了一道题,好颓废啊……
这题其实还挺水的,只不过本蒟蒻一直都不太想的进去,所以一直WA,一直懵逼。
其实这题的题意是在n个数中连续取k个,把这k个数都改成一个相同的数m,使得Σabs(a[i]-m)最小。
很显然,当m为当前k个数的中位数时,当前k个数的改动最小。至于为什么,我也不知道……
然后我们就可以把这题转化为一个滑动窗口的题目,总共有n-k+1个窗口,求当前窗口的改动最小值。
因为是滑动窗口,需要加点、删点,还要取中位数和求和,我们不难想到平衡树。
除了求和那一段我卡了一会,其他的都挺水的。
注意:加点和删点时记得注意对节点所在子树权值和的修改。主要是我也不知道为什么我忘了这一点了,然后就一直WA……
orz hzwer,最后还是看他的代码改的程序,最后AC,不愧是一代神犇
附上AC代码:
#include <cstdio>#include <cstdlib>#include <cctype>#include <algorithm>#define N 100010using namespace std;struct tree{long long sum,w,g,rnd,size;}t[N];int son[N][2],rt;long long n,m,a[N],ans,size,now,tmp,sum1,sum2,mid;inline char nc(){static char ch[100010],*p1=ch,*p2=ch;return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;}inline void read(long long &a){static char c=nc();long long f=1;for (;!isdigit(c);c=nc()) if (c=='-') f=-1;for (a=0;isdigit(c);a=a*10+c-'0',c=nc());a*=f;return;}inline void updata(int k){t[k].size=t[son[k][0]].size+t[son[k][1]].size+t[k].g;t[k].sum=t[son[k][0]].sum+t[son[k][1]].sum+t[k].w*t[k].g;return;}inline void turn(int &k,long long x){int p=son[k][x];son[k][x]=son[p][x^1];son[p][x^1]=k;updata(k),updata(p),k=p;return;}inline void ist(int &k,long long x){if (k==0){k=++size;t[k].w=x,t[k].rnd=rand();t[k].g=t[k].size=1,t[k].sum=x;return;}++t[k].size,t[k].sum+=x;if (t[k].w==x) ++t[k].g;else if (t[k].w<x){ist(son[k][1],x);if (t[son[k][1]].rnd<t[k].rnd) turn(k,1);}else {ist(son[k][0],x);if (t[son[k][0]].rnd<t[k].rnd) turn(k,0);}return;}inline void del(int &k,long long x){if (!k) return;if (t[k].w==x){if (t[k].g>1){--t[k].g,--t[k].size,t[k].sum-=x;return;}if (son[k][0]*son[k][1]==0) k=son[k][0]+son[k][1];else if (t[son[k][0]].rnd<t[son[k][1]].rnd) turn(k,0),del(k,x);else turn(k,1),del(k,x);}else {--t[k].size;if (t[k].w<x) t[k].sum-=x,del(son[k][1],x);else t[k].sum-=x,del(son[k][0],x);}return;}inline void find(int k,long long x){if (!k) return;if (x>t[son[k][0]].size&&x<=t[son[k][0]].size+t[k].g){sum1+=t[son[k][0]].sum+(x-t[son[k][0]].size-1)*t[k].w;sum2+=t[son[k][1]].sum+(t[son[k][0]].size+t[k].g-x)*t[k].w;mid=t[k].w;}else if (x<=t[son[k][0]].size){sum2+=t[k].g*t[k].w+t[son[k][1]].sum;find(son[k][0],x);}else {sum1+=t[k].g*t[k].w+t[son[k][0]].sum;find(son[k][1],x-t[son[k][0]].size-t[k].g);}return;}inline void work(){sum1=sum2=0;long long k=(m+1)>>1;find(rt,k);ans=min(ans,mid*(k-1)-sum1+sum2-mid*(m-k));return;}int main(void){read(n),read(m);for (int i=1; i<=n; ++i) read(a[i]);int j=1;ans=0x7fffffffffffffff;for (int i=1; i<=m; ++i) ist(rt,a[i]);work();for (int i=m+1; i<=n; ++i) del(rt,a[i-m]),ist(rt,a[i]),work();printf("%lld",ans);return 0;}
阅读全文
0 0
- 【BZOJ】1112 [POI2008]砖块Klo 平衡树
- BZOJ 1112: [POI2008]砖块Klo 平衡树,思维,枚举
- 【BZOJ 1112】 [POI2008]砖块Klo
- bzoj 1112 [POI2008]砖块Klo
- BZOJ 1112: [POI2008]砖块Klo 线段树维护区间中位数
- BZOJ 1112 POI2008 砖块Klo Treap
- BZOJ 1112 [POI2008]砖块Klo Treap
- bzoj 1112: [POI2008]砖块Klo(splay)
- bzoj 1112: [POI2008]砖块Klo treap
- 【BZOJ 1112】Poi2008砖块Klo treap
- BZOJ 1112: [POI2008]砖块Klo treap
- BZOJ 1112 [POI2008]砖块Klo Treap
- 1112: [POI2008]砖块Klo
- 1112: [POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)
- 【BZOJ】【P1112】【POI2008】【砖块Klo】【题解】【map】
- bzoj-1112 砖块Klo
- 1112: [POI2008]砖块Klo Splay+中位数
- TCP协议相关问题
- 推荐阅读:SpringMVC对象绑定时自定义名称对应关系(1)
- RxJava 1.x 使用Operator构造业务逻辑1-map()
- arcgis 生成 多边形缓冲区
- DriveInfo类
- 【BZOJ】1112 [POI2008]砖块Klo 平衡树
- java 设计模式详解
- RGB与Gray
- TCP-Socket-HTTP的关系
- C++内存对齐原则
- 两种方法求LCS(最长公共子序列)
- 亲和数(220/284)
- MessageBox()函数小结
- 机器学习岗位的面试准备——总结1