题解:CF1830B The BOSS Can Count Pairs

节选自:2025.7.8校测

在暴力上优化就可以了。

考虑到 \(b_i + b_j\) 最多只有 \(2 \times n\),那么 \(a_i\)\(a_j\) 中一定有一个小于 \(\sqrt{2 \times n}\),于是我们枚举这个值 \(k\),找到所有的 \(a_i = k\) 并将 \(b_i\) 加入桶里,这时我们再来枚举大于 \(\sqrt{2 \times n}\) 的那一个数 \(a_j\),并将答案加上桶里 \(a_j \times k - b_j\) 的次数即可。由于对于每一对满足条件的 \((i, j)\),我们都是枚举的小的值,再去找大的值,而这只会枚举一次,因此不需要对最终的答案除以 \(2\)

不过还有一点,那就是 \(a_i = a_j = k\) 的情况,这时 \((i, j)\) 就可能会被枚举两次,因此我们在一开始将所有的 \(a_i = k\)\(b_i\) 加入桶里时,就边加入边统计答案,此时一个 \(a_j\) 就只会和 \(i < j\)\(a_i\) 产生贡献,那么这种情况也只会被枚举一次了。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 9;
int a[N], b[N], bas[N], n, T;
signed main(){
	scanf("%lld", &T);
	while(T--){
		scanf("%lld", &n);
		for(int i = 1; i <= n; i++)
			scanf("%lld", &a[i]);
		for(int i = 1; i <= n; i++)
			scanf("%lld", &b[i]);
		int res = 0;
		for(int i = 1; i <= sqrt(n * 2) + 1; i++){
			memset(bas, 0, sizeof(bas));
			for(int j = 1; j <= n; j++)
				if(a[j] == i){
					if(a[j] * i - b[j] >= 1 && a[j] * i - b[j] <= n)
						res += bas[a[j] * i - b[j]];
					bas[b[j]]++;
				}	
			for(int j = 1; j <= n; j++)
				if(a[j] > i && a[j] * i - b[j] >= 1 && a[j] * i - b[j] <= n)
					res += bas[a[j] * i - b[j]];
		}
		printf("%lld\n", res);
	}
	return 0;
}
posted @ 2025-07-09 15:24  Orange_new  阅读(12)  评论(0)    收藏  举报