【BZOJ】【P1112】【POI2008】【砖块Klo】【题解】【map】

来源:互联网 发布:社交行为数据挖掘 编辑:程序博客网 时间:2024/05/01 12:42

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1112

做法非常好想

线性枚举连续长为k的区间,找出中位数然后计算答案,平衡树搞一搞就好了

好久不写Treap于是就写挂了……

然后开始yy用stl如何维护中位数

其实非常简单……

一开始吧前k个数sort一遍,前一半后一半各扔进map里

那么中位数一定就是后一半map的最小值

修改的时候判断一下要修改哪个map,改就好了

改完判断一下两个map的元素数是否相差k%2个

不是就把多了的哪个的最小/大值扔到另一个map里

这样就搞完了

在bzoj上rank5 码长也很短……

不过这再次提醒我要复习Treap了……

Code:

#include<bits/stdc++.h>using namespace std;const int maxn=1e5+10;typedef long long LL;map<int,int>M1,M2;LL sum1=0,sum2=0;int size1,size2;int getint(){int res=0;char c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))res=(res<<1)+(res<<3)+c-'0',c=getchar();return res;}int n,k;LL ans=1LL<<61;int a[maxn],b[maxn];int main(){n=getint();k=getint();for(int i=1;i<=n;i++)a[i]=getint(),b[i]=a[i];sort(b+1,b+1+k);for(int i=1;i<=k/2;i++)M1[b[i]]++,sum1+=b[i],size1++;for(int i=k/2+1;i<=k;i++)M2[b[i]]++,sum2+=b[i],size2++;int md=M2.begin()->first;ans=sum2-size2*md+size1*md-sum1;for(int i=2;i+k-1<=n;i++){int x=a[i-1],y=a[i+k-1];if(x<md){size1--;if(!--M1[x])M1.erase(x);sum1-=x;}else{size2--;if(!--M2[x])M2.erase(x);sum2-=x;}if(y<md){size1++;M1[y]++;sum1+=y;}else{size2++;M2[y]++;sum2+=y;}if(size2>size1+k%2){int mn=M2.begin()->first;size2--;if(!--M2[mn])M2.erase(mn);sum2-=mn;size1++;M1[mn]++;sum1+=mn;}elseif(size2<size1+k%2){int mn=(--M1.end())->first;size1--;if(!--M1[mn])M1.erase(mn);sum1-=mn;size2++;M2[mn]++;sum2+=mn;}md=M2.begin()->first;ans=min(ans,sum2-size2*md+size1*md-sum1);}cout<<ans<<endl;return 0;} 



0 0
原创粉丝点击