题解: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;
}
本文来自博客园,作者:Orange_new,转载请注明原文链接:https://www.cnblogs.com/JPGOJCZX/p/18974894

浙公网安备 33010602011771号