三分(凸函数)
题目链接:https://www.cometoj.com/contest/33/problem/B
题目大意:一个小区中任意两个房子的高度差必须要小于等于M米。因此房地产商必须要调整房子的高度,使得任意两个房子的高度差均小于等于M米。每个房子只能改变一次高度,将一个房子的高度改变k米的花费是k^2万元,求房地产商最低要花费多少万元。
具体思路:三分这些楼层中可以存在的最小高度。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 # define inf 0x3f3f3f3f 5 const int maxn = 2e5+100; 6 ll n,m; 7 ll a[maxn]; 8 ll cal(ll tmp) 9 { 10 ll ans=0; 11 for(int i=1; i<=n; i++) 12 { 13 if(a[i]<tmp) 14 ans+=(tmp-a[i])*(tmp-a[i]); 15 else if(a[i]>tmp+m) 16 ans+=(a[i]-tmp-m)*(a[i]-m-tmp); 17 } 18 return ans; 19 } 20 ll solve(ll l,ll r){ 21 ll mid,midd; 22 ll ans=0; 23 while(l<r-1) 24 { 25 mid=(l+r)/2ll; 26 midd=(mid+r)/2ll; 27 if(cal(mid)>=cal(midd)){ 28 ans=cal(mid); 29 l=mid; 30 } 31 else 32 { 33 ans=cal(midd); 34 r=midd; 35 } 36 } 37 return ans; 38 } 39 int main() 40 { 41 ll minn=inf,maxx=-inf; 42 scanf("%d %d",&n,&m); 43 for(int i=1; i<=n; i++) 44 { 45 scanf("%d",&a[i]); 46 minn=min(minn,a[i]); 47 maxx=max(maxx,a[i]); 48 } 49 printf("%lld\n",solve(minn,maxx)); 50 }