Codeforces 960B Minimize the error

You are given two arrays A and B, each of size n. The error, E, between these two arrays is defined . You have to perform exactly k1 operations on array A and exactly k2 operations on array B. In one operation, you have to choose one element of the array and increase or decrease it by 1.

Output the minimum possible value of error after k1 operations on array A and k2 operations on array B have been performed.

Input

The first line contains three space-separated integers n (1 ≤ n ≤ 103), k1 and k2 (0 ≤ k1 + k2 ≤ 103, k1 and k2 are non-negative) — size of arrays and number of operations to perform on A and B respectively.

Second line contains n space separated integers a1, a2, ..., an ( - 106 ≤ ai ≤ 106) — array A.

Third line contains n space separated integers b1, b2, ..., bn ( - 106 ≤ bi ≤ 106)— array B.

Output

Output a single integer — the minimum possible value of after doing exactly k1 operations on array A and exactly k2 operations on array B.

Examples
Input
2 0 0
1 2
2 3
Output
2
Input
2 1 0
1 2
2 2
Output
0
Input
2 5 7
3 4
14 4
Output
1
Note

In the first sample case, we cannot perform any operations on A or B. Therefore the minimum possible error E = (1 - 2)2 + (2 - 3)2 = 2.

In the second sample case, we are required to perform exactly one operation on A. In order to minimize error, we increment the first element of A by 1. Now, A = [2, 2]. The error is now E = (2 - 2)2 + (2 - 2)2 = 0. This is the minimum possible error obtainable.

In the third sample case, we can increase the first element of A to 8, using the all of the 5 moves available to us. Also, the first element of B can be reduced to 8 using the 6 of the 7 available moves. Now A = [8, 4] and B = [8, 4]. The error is now E = (8 - 8)2 + (4 - 4)2 = 0, but we are still left with 1 move for array B. Increasing the second element of B to 5 using the left move, we get B = [8, 5] and E = (8 - 8)2 + (4 - 5)2 = 1.


题意:给你两个数列,然后你能对A,B数列中任一个元素加减1,这样的次数分别为k1,k2次,然后就是相应的元素相减开方求和,必须全部用完,然后问你最小的答案是多少?


解题思路:这道题目思路很清晰,就是让你每一对应元素都尽量相等。我们可以把一开始的数列相减后取绝对值后放入优先队列里(why?)。 然后每一次取出最大值来减1,如果最大值已经为0了,那么我们把 剩下的操作步数%2 压入到队列中就行了。

我们都知道,你把一个最大的元素减1比不是最大元素减1取得的效果要好。所以我们每一次都是取最大的那个元素来减,但是在这个思考过程中,我找到了题目可以出的坑点。因为这个数据范围有点小,所以你可以用优先队列模拟一下就能过。但是我们假设这个n值过1e5尼,你会怎么优雅的暴力,由于博主目前水平比较菜,所以还没想出具体的解决方案。

1.3 3 3 3 2 2 2 2 2 2 2 2 2  (一直重复一个数,然后出现另一个数)

2. 1 2 3 4 5 6 (一直是有递进的数)

3.0 0 0 0 0 0 0 (但是k1+k2还有,这种情况被我自己hack掉了,没看清楚题)

我为什么觉得这里可以出坑,是因为你每次需要的是取出最大值来减,但是你不知道你应该减多少,因为当你减到与第二大的数相同的时候,你这时候应该停下来,然后减另一个数,因为你一减到底的话,这个答案有可能不是最优解,那这就蛋疼了。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1010;
int numa[maxn],numb,n,k1,k2,ans[maxn];
priority_queue<int> qu;
int main(){
	int i,j;
	scanf("%d%d%d",&n,&k1,&k2);
	k1+=k2;
	while(!qu.empty()) qu.pop();
 	for(i=0;i<n;i++){
		scanf("%d",&numa[i]);
	}
	for(i=0;i<n;i++){
		scanf("%d",&numb);
		numa[i]-=numb;
		if(numa[i]<0) numa[i]*=-1;
		qu.push(numa[i]);
	}
	while(k1){
		int t=qu.top();qu.pop();
		if(t==0){
			k1%=2;
			qu.push(k1);
			break;
		}	
		else{
			qu.push(t-1);
		}
		k1--;
	}
	long long ans=0;
	while(!qu.empty()){
		long long te=qu.top();qu.pop();
		ans+=te*te;
	}
	printf("%I64d\n",ans);
	return 0;
}


猜你喜欢

转载自blog.csdn.net/bao___zi/article/details/79855971