2023河南萌新联赛第(五)场:郑州轻工业大学 I - 双指针
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给定一个数组 a a a 和数组 b b b ,两个数组的长度都为 n n n, 请选择分别两个下标 i , j i, j i,j 且 i , j i, j i,j 满足条件 1 ≤ i < j ≤ n 1 \leq i < j \leq n 1≤i<j≤n, 求有多少对 i , j i, j i,j 满足 a i × a j = b i × b j a_i \times a_j = b_i \times b_j ai×aj=bi×bj 。
输入描述:
本题包含多组数据
第一行包含一个正整数 T T T( 1 ≤ T ≤ 1 × 1 0 5 1\leq T \leq 1 \times 10^{5} 1≤T≤1×105)。
对于每组数据:
第一行包含一个正整数 n ( 1 ≤ n ≤ 2 × 1 0 5 ) n(1 \leq n \leq 2 \times 10^5 ) n(1≤n≤2×105) 。
接下来 2 2 2 行
第1行包含 n n n 个整数 a 1 , a 2 , a 3 . . . a n ( 1 ≤ a i ≤ 2 × 1 0 5 ) a_1, a_2, a_3 ... a_n(1 \leq a_i \leq 2\times10^5) a1,a2,a3...an(1≤ai≤2×105) 。
第2行包含 n n n 个整数 b 1 , b 2 , b 3 . . . b n ( 1 ≤ b i ≤ 2 × 1 0 5 ) b_1, b_2, b_3 ... b_n(1 \leq b_i \leq 2\times10^5) b1,b2,b3...bn(1≤bi≤2×105) 。
∑ i = 1 T n ≤ 2 × 1 0 5 \sum_{i=1}^{T} n \leq 2 \times 10^{5} ∑i=1Tn≤2×105
输出描述:
对于每组数据:
输出一行表示有多少对 i , j i, j i,j 满足 a i × a j = b i × b j a_i \times a_j = b_i \times b_j ai×aj=bi×bj 。
- 关键词:思维,STL
- 给定一个数组 a a a 和数组 b b b,问有多少对 i , j i,j i,j 满足 1 ≤ i < j ≤ n 1 ≤ i < j ≤ n 1≤i<j≤n 使得 a i × a j = b i × b j a_i × a_j = b_i × b_j ai×aj=bi×bj 。
- 将原式转化为 a i / b i = b j / a j a_i/b_i = b_j/a_j ai/bi=bj/aj,令 c i = a i / b i c_i = a_i/b_i ci=ai/bi , d j = b j / a j d_j = b_j/a_j dj=bj/aj,这样问题就转化成有多少对 i i i, j j j 满足 1 ≤ i < j ≤ n 1 ≤ i < j ≤ n 1≤i<j≤n 使得 c i = d j c_i = d_j ci=dj。
- 使用 m a p map map 分别统计数组 c c c 和数组 d d d 中每个数出现的次数并 计算答案。注意由于 i < j i < j i<j 当 a i / b i a_i/b_i ai/bi = b i / a i b_i/a_i bi/ai 时处理不当答案 可能会有冗余计算,注意避免这种情况。如果担心 d o u b l e double double 精度问题可以用分数代替。注意答案开 l o n g long long l o n g long long。
输入
2
5
3 2 2 2 3
3 1 2 4 2
5
2 1 1 1 3
4 2 4 3 1
输出
2
1
import java.io.*;
import java.util.HashMap;
public class Main {
public static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(bf.readLine());
while (T-- > 0) {
HashMap<String, Integer> cnt = new HashMap<>();
int n = Integer.parseInt(bf.readLine());
int[] a = new int[n];
int[] b = new int[n];
String[] str = bf.readLine().split(" ");
for (int i = 0; i < n; i++) {
a[i] = Integer.parseInt(str[i]);
}
str = bf.readLine().split(" ");
for (int i = 0; i < n; i++) {
b[i] = Integer.parseInt(str[i]);
}
long res = 0;
for (int i = 0; i < n; i++) {
int d = gcd(a[i], b[i]);
a[i] /= d;
b[i] /= d;
String s1 = a[i] + " " + b[i];
String s2 = b[i] + " " + a[i];
res += cnt.getOrDefault(s2, 0);
cnt.put(s1, cnt.getOrDefault(s1, 0) + 1);
}
bw.write(res + "\n");
}
bw.close();
}
}