BZOJ1112: [POI2008]砖块Klo
来源:互联网 发布:怎么学淘宝运营 编辑:程序博客网 时间:2024/03/29 04:01
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1112
题目大意:N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动 作完成任务.
题解:我们看看n是106于是我们可以枚举k,是O(n)的,那么看看时间复杂度,就需要一个logN的算法来删除一个数,加入一个数,寻找第k个数,于是平衡树即可!时间复杂度:NlogN;
实际上刚开始想的是二分次数+二分长度,想想应该也是可行的,只不过在答案验证上,可以自己想想,反正我不知道!
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #define maxn 100005 7 #define ll long long 8 #define linf 9223372036854775807LL 9 using namespace std; 10 int n,k,root,mid,mmid,sz; 11 ll tmp; 12 ll sum1,sum2,ans; 13 int a[maxn]; 14 int ls[maxn],rs[maxn],size[maxn],w[maxn],rnd[maxn]; 15 ll sum[maxn],v[maxn]; 16 int read() 17 { 18 int x=0; char ch; bool bo=0; 19 while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1; 20 while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); 21 if (bo) return -x; return x; 22 } 23 void updata(int k) 24 { 25 sum[k]=sum[ls[k]]+sum[rs[k]]+w[k]*v[k]; 26 size[k]=size[ls[k]]+size[rs[k]]+w[k]; 27 } 28 void rturn(int &k) 29 { 30 int t=ls[k]; ls[k]=rs[t]; rs[t]=k; updata(k); updata(t); k=t; return; 31 } 32 void lturn(int &k) 33 { 34 int t=rs[k]; rs[k]=ls[t]; ls[t]=k; updata(k); updata(t); k=t; return; 35 } 36 void ins(int &k,int val) 37 { 38 if (!k) 39 { 40 k=++sz; size[k]=w[k]=1; v[k]=sum[k]=val; rnd[k]=rand(); return ; 41 } 42 size[k]++; sum[k]+=val; 43 if (val==v[k]) w[k]++; 44 if (v[k]>val){ins(ls[k],val); if (rnd[ls[k]]>rnd[k]) rturn(k);} 45 if (v[k]<val){ins(rs[k],val); if (rnd[rs[k]]>rnd[k]) lturn(k);} 46 updata(k); 47 } 48 void del(int &k,int val) 49 { 50 if (!k) return ; 51 if (v[k]==val) 52 { 53 if (w[k]) 54 { 55 w[k]--; size[k]--; sum[k]-=val; return ; 56 } 57 if (ls[k]*rs[k]==0) k=ls[k]+rs[k]; 58 else 59 { 60 if (rnd[ls[k]]>rnd[rs[k]]) {rturn(k); del(k,val);} 61 else {lturn(k); del(k,val);} 62 } 63 } 64 else if (v[k]>val) {sum[k]-=val; size[k]--; del(ls[k],val);} 65 else {sum[k]-=val; size[k]--; del(rs[k],val);} 66 } 67 void init() 68 { 69 n=read(); k=read(); mmid=k/2+1; ans=linf; 70 for(int i=1; i<=n; i++) a[i]=read(); 71 } 72 void find(int k,int rank) 73 { 74 if(!k)return; 75 if(rank>size[ls[k]]&&rank<=size[ls[k]]+w[k]) 76 { 77 sum1+=(sum[ls[k]]+(rank-size[ls[k]]-1)*v[k]); 78 sum2+=(sum[rs[k]]+(size[ls[k]]+w[k]-rank)*v[k]); 79 tmp=v[k]; 80 } 81 else if(rank<=size[ls[k]]) 82 { 83 sum2+=(v[k]*w[k]+sum[rs[k]]); 84 find(ls[k],rank); 85 } 86 else 87 { 88 sum1+=(v[k]*w[k]+sum[ls[k]]); 89 find(rs[k],rank-size[ls[k]]-w[k]); 90 } 91 } 92 void getans() 93 { 94 sum1=sum2=0; 95 find(root,mmid); 96 ll sum=(mmid-1)*tmp-sum1+sum2-(k-mmid)*tmp; 97 if(sum<ans)ans=sum; 98 } 99 void solve()100 {101 root=0;102 for (int i=1; i<=k; i++) ins(root,a[i]); 103 getans();104 for (int i=k+1; i<=n; i++)105 {106 del(root,a[i-k]); ins(root,a[i]);107 getans();108 }109 printf("%lld\n",ans);110 }111 int main()112 {113 init();114 solve();115 }
0 0
- bzoj1112 [POI2008]砖块Klo
- bzoj1112【poi2008】砖块klo
- 【POI2008】【BZOJ1112】砖块Klo
- BZOJ1112: [POI2008]砖块Klo
- bzoj1112: [POI2008]砖块Klo
- 【bzoj1112】[POI2008]砖块Klo
- [bzoj1112][POI2008]砖块Klo
- Bzoj1112:[POI2008]砖块Klo:splay
- 【BZOJ1112】[POI2008]砖块Klo【Splay】
- BZOJ1112: [POI2008]砖块Klo Treap
- [BZOJ1112][POI2008]砖块Klo(splay)
- bzoj1112 POI2008 砖块Klo 树状数组
- [主席树] BZOJ1112: [POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)
- [BZOJ1112]砖块klo Treap
- 【BZOJ1112】砖块Klo
- 【bzoj1112】【poi2008】【砖块】【treap】
- [POI2008]砖块Klo
- BZOJ1854: [Scoi2010]游戏
- BZOJ1724: [Usaco2006 Nov]Fence Repair 切割木板
- BZOJ1079: [SCOI2008]着色方案
- BZOJ1237: [SCOI2008]配对
- AndroidStudio——数据存储之内部存储
- BZOJ1112: [POI2008]砖块Klo
- 解决Android布局添加EditText之后无法预览的问题
- POJ 2728 Desert King 最优比率生成树
- DP——由蒟蒻到神犇的进阶之路
- jquery学习160815
- 《将博客搬至CSDN》
- 【codevs 1158】尼克的任务
- 大津法---OTSU算法
- 计算几何总结