codeforces#439 D. Devu and his Brother (二分)
阿新 • • 發佈:2019-03-04
最大 sca sha main cout 修改 ace \n 最小值
題意:給出a數組和b數組,他們的長度最大1e5,元素範圍是1到1e9,問你讓a數組最小的數比b數組最大的數要大需要的最少改變次數是多少。每次改變可以讓一個數加一或減一
分析:枚舉a數組和b數組的所有的元素x,作為他們的界限,也就是說a數組所有的數要大於等於x,b數組所有的數要小於等於x,再利用前綴和+二分,分別求出ab數組需要改變的次數,在所有的方案中取一個最小值
代碼:
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e5+10; ll sum1[maxn],sum2[maxn]; int num1[maxn],num2[maxn]; int main() { int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&num1[i]); for(int i=1;i<=m;i++) scanf("%d",&num2[i]); sort(num1+1,num1+1+n); sort(num2+1,num2+1+m); for(int i=1;i<=n;i++) sum1[i]=sum1[i-1]+num1[i]; for(int i=1;i<=m;i++) sum2[i]=sum2[i-1]+num2[i]; ll ans=1e18; for(int a=1;a<=n+m;a++) { int i; if(a<=n)i=num1[a]; else i=num2[a-n]; ll ans1,ans2; if(num1[1]>=i)ans1=0; else { int st=1,en=n; while(st!=en) { int md=(st+en)/2; if(num1[md+1]<=i)st=md+1;//可以修改的下標 else en=md; } ans1=(ll)i*st-sum1[st]; } if(num2[m]<=i)ans2=0; else { int st=1,en=m; while(st!=en) { int md=(st+en)/2; if(num2[md]>=i)en=md; else st=md+1; } ans2=sum2[m]-sum2[st-1]-(ll)i*(m-st+1); } //cout<<i<<" "<<ans1<<" "<<ans2<<endl; ans=min(ans1+ans2,ans); } printf("%lld\n",ans); return 0; }
codeforces#439 D. Devu and his Brother (二分)