【2022 省选训练赛 Contest 05 B】卷积练习题(暴力)(性质)

卷积练习题

题目链接:2022 省选训练赛 Contest 05 B

题目大意

给你两个数组,要你求它们各选一个数出来相减的绝对值的平方下取整的结果的和。
然后两个数组里面数的和在 1e7 以内。

思路

考虑从数组和的范围入手。
首先根据第二个部分分不难想到一种做法:记录每个数的出现次数,然后暴力匹配。
然后你再看会这个范围,我们考虑它最多会出现多少种数,而结果是只会出现 \(\sqrt{V}\) 次的(\(V\) 就是数组数的和)
(考虑 \(1+2+3+...+x=\dfrac{x(x-1)}{2}\)

所以这题就是大概每边 \(3000\) 个数,直接暴力就可以过。

然后 WYC 大佬还说如果再大一点比如到 \(1e8\) 的话可以分段搞,前面的用卷积(翻转一边的数组得到相差值为一个值的个数),后面就像这样暴力搞。

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long

using namespace std;

int n, a[1000001], b[1000001];
int aa[1000001], bb[1000001];
int ma, mb, numa[1000001], numb[1000001];
ll ans;

int clac(int x, int y) {
	return floor(sqrt(abs(x - y)));
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
	
	memcpy(aa, a, sizeof(aa)); memcpy(bb, b, sizeof(bb));
	sort(aa + 1, aa + n + 1); sort(bb + 1, bb + n + 1);
	ma = unique(aa + 1, aa + n + 1) - aa - 1; mb = unique(bb + 1, bb + n + 1) - bb - 1;
	for (int i = 1; i <= n; i++) numa[lower_bound(aa + 1, aa + ma + 1, a[i]) - aa]++;
	for (int i = 1; i <= n; i++) numb[lower_bound(bb + 1, bb + mb + 1, b[i]) - bb]++;
	
	for (int i = 1; i <= ma; i++)
		for (int j = 1; j <= mb; j++)
			ans += 1ll * numa[i] * numb[j] * clac(aa[i], bb[j]);
	printf("%lld", ans); 
	
	return 0;
}
posted @ 2022-02-24 07:37  あおいSakura  阅读(61)  评论(0编辑  收藏  举报