Bzoj1112:[POI2008]砖块Klo:splay
来源:互联网 发布:墨子4号 知乎 编辑:程序博客网 时间:2024/04/28 01:43
题目链接:1112:[POI2008]砖块Klo
原题目是要输出最终高度的,代码中有体现
显然一段区间都变成某个数且代价最小,那么就变成中位数
所以我们维护中位数即可,上splay
一不小心把树建反成左大右小了QAQ
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define LL long longusing namespace std;const int maxn=1000010;int n,m,mn,pos,root=0,cnt=0;LL ans=1e16,a[maxn],ans2;struct Nodes{int c[2],fa,size;LL s,val;};struct splay_tree{Nodes t[maxn]; void push_up(int x){t[x].size=t[t[x].c[0]].size+t[t[x].c[1]].size+1;t[x].s=t[t[x].c[0]].s+t[t[x].c[1]].s+t[x].val;}void rotate(int p,int x){ int mark= p==t[x].c[1]; int y=t[p].c[mark^1],z=t[x].fa; if (t[z].c[0]==x) t[z].c[0]=p; if (t[z].c[1]==x) t[z].c[1]=p; if (y) t[y].fa=x;t[x].c[mark]=y; t[x].fa=p; t[p].fa=z; t[p].c[mark^1]=x; push_up(x); } void splay(int p,int k){ while (t[p].fa!=k){ int x=t[p].fa,y=t[x].fa; if (y==k) rotate(p,x); else if (p==t[x].c[0]^x==t[y].c[0]) rotate(p,x),rotate(p,y); else rotate(x,y),rotate(p,x); } push_up(p); if (!k) root=p; return; } void new_splay(int v,int f){t[++cnt].fa=f; t[cnt].val=v;t[cnt].size=1; t[cnt].s=v;if (f) t[f].c[t[f].val>v]=cnt; } void ins(int p,LL v){if(!p){new_splay(v,0),splay(cnt,0);return;}int fat=p;while (p){fat=p;if (t[p].val>v) p=t[p].c[1];else p=t[p].c[0];}new_splay(v,fat);splay(cnt,0); } void del(int p){splay(p,0); int tmp=t[p].c[0];t[t[p].c[0]].fa=0; t[t[p].c[1]].fa=0;if (!t[p].c[1]){root=t[p].c[0];return;}if (!t[p].c[0]){root=t[p].c[1];return;}while (t[tmp].c[1]) tmp=t[tmp].c[1];splay(tmp,0);t[t[p].c[1]].fa=tmp;t[tmp].c[1]=t[p].c[1];push_up(tmp); } int findkth(int p,int k){if (t[t[p].c[0]].size+1==k) return p;if (t[t[p].c[0]].size+1<k) return findkth(t[p].c[1],k-t[t[p].c[0]].size-1);else return findkth(t[p].c[0],k); } void getans(int i){splay(findkth(root,mn),0);LL mid=t[root].val; int tmp=root;LL ret=mid*t[t[tmp].c[0]].size-t[t[tmp].c[0]].s;ret=ret+t[t[tmp].c[1]].s-mid*t[t[tmp].c[1]].size;ret=-ret;if (ret<ans){ans=ret;pos=i;ans2=mid;} }}s;int main(){scanf("%d%d",&n,&m); mn=(m+1)/2;for (int i=1;i<=n;++i) scanf("%lld",&a[i]);for (int i=1;i<=m;++i) s.ins(root,a[i]);s.getans(1);for (int i=m+1;i<=n;++i){s.del(i-m); s.ins(root,a[i]);s.getans(i-m+1);}printf("%lld\n",ans);for (int i=pos;i<=pos+m-1;++i) a[i]=ans2;for (int i=1;i<=n;++i) printf("%lld\n",a[i]);}
1 0
- Bzoj1112:[POI2008]砖块Klo:splay
- 【BZOJ1112】[POI2008]砖块Klo【Splay】
- [BZOJ1112][POI2008]砖块Klo(splay)
- bzoj1112 [POI2008]砖块Klo
- bzoj1112【poi2008】砖块klo
- 【POI2008】【BZOJ1112】砖块Klo
- BZOJ1112: [POI2008]砖块Klo
- bzoj1112: [POI2008]砖块Klo
- 【bzoj1112】[POI2008]砖块Klo
- [bzoj1112][POI2008]砖块Klo
- BZOJ1112: [POI2008]砖块Klo Treap
- bzoj1112 POI2008 砖块Klo 树状数组
- [主席树] BZOJ1112: [POI2008]砖块Klo
- 两道Splay小结--bzoj1112: [POI2008]砖块Klo&bzoj1588: [HNOI2002]营业额统计
- 1112: [POI2008]砖块Klo Splay+中位数
- bzoj 1112: [POI2008]砖块Klo(splay)
- bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)
- [BZOJ1112]砖块klo Treap
- Android4.4的zygote进程
- 虚拟机Ubuntu Server(宿主Win7)挂载U盘
- 定义回调函数的方法
- Http协议详解
- c++实验2 正整数类
- Bzoj1112:[POI2008]砖块Klo:splay
- java中的类修饰符、成员变量修饰符、方法修饰符
- 第4章 Internet地址
- Linux gpg --加密和数字签名工具
- CentOS 6使用rpm方式安装JDK8
- Linux grep --搜索工具
- java注解
- php编写冒泡排序
- Eclipse Java Code Style设置自动注释模板