【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1112
【题目大意】
给出一个数列,对于一个操作,你可以对一个数+1,或者一个数-1,
问若使得数列中出现长度为m的连续相同的数,最少需要的操作数。
【题解】
我们发现对于固定区间求最小操作,等价于求区间中数距离中位数差值和最小,
我们发现区间中位数可以利用主席树求区间kth来实现,
同时在主席树上维护权值线段树的区间真值和,那么对于每个区间中的数,
就能分别维护比中位数小的部分的和以及比中位数大的部分的和,
分别与中位数的倍数做加减运算即可。
我们枚举区间的位置,保留最小值,复杂度O(nlogn)。
【代码】
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100010;
typedef long long LL;
int n,m,i,x,y,z,ans;
int l[N*40],r[N*40],v[N*40],tot,root[N],num[N];
LL s[N*40];
int cmp(int i,int j){return num[i]<num[j];}
int rk[N],sa[N]; //sa:该数字对应原数列的下标
int build(int a,int b){
int x=++tot; v[x]=s[x]=0;
if(a==b)return x;
int mid=(a+b)>>1;
return l[x]=build(a,mid),r[x]=build(mid+1,b),x;
}
// x版本c位置+p,在s中记录+num[sa[c]],统计权值线段树上真值的区间和。
int change(int x,int a,int b,int c,int p){
int y=++tot;v[y]=v[x]+p;s[y]=s[x]+num[sa[c]];
if(a==b)return y;
int mid=(a+b)>>1;
if(c<=mid)l[y]=change(l[x],a,mid,c,p),r[y]=r[x];
else l[y]=l[x],r[y]=change(r[x],mid+1,b,c,p);
return y;
}
int kth(int x,int y,int a,int b,int k){
if(a==b)return a;
int mid=(a+b)>>1;
if(v[l[y]]-v[l[x]]>=k)return kth(l[x],l[y],a,mid,k);
else return kth(r[x],r[y],mid+1,b,k-v[l[y]]+v[l[x]]);
}
LL abs(LL x){return x<0?-x:x;}
LL query(int x,int y,int a,int b,int c){
if(a==b)return 1LL*abs(num[sa[a]]-num[sa[c]])*(v[y]-v[x]);
int mid=(a+b)>>1;
if(c<=mid){
return query(l[x],l[y],a,mid,c)+s[r[y]]-s[r[x]]-1LL*num[sa[c]]*(v[r[y]]-v[r[x]]);
}else{
return query(r[x],r[y],mid+1,b,c)+1LL*num[sa[c]]*(v[l[y]]-v[l[x]])-(s[l[y]]-s[l[x]]);
}
}
int main(){
while(~scanf("%d%d",&n,&m)){
root[0]=0;tot=0;
for(int i=1;i<=n;i++)scanf("%d",num+i);
for(int i=1;i<=n;i++)sa[i]=i;
sort(sa+1,sa+n+1,cmp);
for(int i=1;i<=n;i++)rk[sa[i]]=i;
build(1,n);
for(int i=1;i<=n;i++)root[i]=change(root[i-1],1,n,rk[i],1);
LL ans=0x3f3f3f3f3f3f3f3f;
for(int i=1;i<=n-m+1;i++){
int id=kth(root[i-1],root[i+m-1],1,n,(m+1)>>1);
ans=min(ans,query(root[i-1],root[i+m-1],1,n,id));
}printf("%lld\n",ans);
}return 0;
}
BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)
原文:http://www.cnblogs.com/forever97/p/bzoj1112.html