题目描述
Bobo has two sequences of integers {a1,a2,…,an}{a_1, a_2, \dots, a_n}{a1,a2,…,an} and {b1,b2,…,bm}{b_1, b_2, \dots, b_m}{b1,b2,…,bm}.
He would like to find
∑i=1n∑j=1m⌊∣ai−bj∣⌋.\sum_{i = 1}^n\sum_{j = 1}^m \lfloor \sqrt{|a_i - b_j|} \rfloor.∑i=1n∑j=1m⌊∣ai−bj∣
⌋.
Note that ⌊x⌋\lfloor x \rfloor⌊x⌋ denotes the maximum integer does not exceed x,
and |x| denotes the absolute value of x.
输入描述:
The input contains at most 30 sets. For each set:
The first line contains 2 integers n, m (1≤n,m≤1051 \leq n, m \leq 10^51≤n,m≤105).
The second line contains n integers a1,a2,…,ana_1, a_2, \dots, a_na1,a2,…,an.
The thrid line contains m integers b1,b2,…,bmb_1, b_2, \dots, b_mb1,b2,…,bm.
(ai,bi≥0,a1+a2+⋯+an,b1+b2+…,bm≤106a_i, b_i \geq 0, a_1 + a_2 + \dots + a_n, b_1 + b_2 + \dots, b_m \leq 10^6ai,bi≥0,a1+a2+⋯+an,b1+b2+…,bm≤106)
输出描述:
For each set,
an integer denotes the sum.
示例1
输入
复制
1 2
1
2 3
输出
复制
2
示例2
输入
复制
2 3
1 2
3 4 5
输出
复制
7
1≤n,m≤1e5,,直接暴力不行,,不过(ai,bi≥0,a1+a2+⋯+an,b1+b2+…,bm≤1e6)通过这个条件可知,,a和b序列会有很多重复数字,可以采取去重后暴力的方法来写。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 1e6 +10;
int a[maxn], b[maxn];
int numa[maxn], numb[maxn];
int tota = 0, totb = 0;
int n, m;
void init()
{
tota = 0, totb = 0;
mem(numa, 0), mem(numb, 0);
mem(a, 0), mem(b, 0);
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
init();
int x;
for(int i = 1; i <= n; i++)
{
scanf("%d", &x);
if(numa[x] == 0)
a[tota++] = x;
numa[x]++;
}
for(int i = 1; i <= m; i++)
{
scanf("%d", &x);
if(numb[x] == 0)
b[totb++] = x;
numb[x]++;
}
long long ans = 0;
for(int i = 0; i < tota; i++)
for(int j = 0; j < totb; j++)
{
ans += 1ll * numa[a[i]] * numb[b[j]] * (long long)(sqrt(fabs(a[i] - b[j])));
}
printf("%lld\n", ans);
}
return 0;
}