题目描述
平面直角坐标系上有 n + m n + m n+m 个点,其中:
- 有 n n n 个 A \rm A A 类点,它们在初始时依次位于位置 ( 1 , 0 ) , ( 2 , 0 ) , ( 3 , 0 ) , … , ( n , 0 ) (1, 0), (2, 0), (3, 0), \dots, (n, 0) (1,0),(2,0),(3,0),…,(n,0)。
- 有 m m m 个 B \rm B B 类点,它们在初始时依次位于位置 ( 0 , 1 ) , ( 0 , 2 ) , ( 0 , 3 ) , … , ( 0 , m ) (0, 1), (0, 2), (0, 3), \dots, (0, m) (0,1),(0,2),(0,3),…,(0,m)。
在某一个时刻, A , B \rm A, B A,B 类点同时开始运动。具体地:
- 对于第 i i i 个 A \rm A A 类点,其以 a i a_i ai 个单位长度每秒的速度向上(即 y y y 轴正方向)匀速运动。特别地,若 a i = 0 a_i = 0 ai=0,则该点始终保持静止。
- 对于第 i i i 个 B \rm B B 类点,其以 b i b_i bi 个单位长度每秒的速度向右(即 x x x 轴正方向)匀速运动。特别地,若 b i = 0 b_i = 0 bi=0,则该点始终保持静止。
你能否帮小 T 解决一个简单的问题:求出有多少点对会在某个时刻相遇,即它们在某一刻共点。
分析
对于两个点如果同为 A \rm A A 类点,或同为 B \rm B B 类点,他们是不会相交的,因为他们的移动方向是不同的,我们假设相交的点编号为 i , j i,j i,j,可以发现他们必然在 ( i , j ) (i,j) (i,j) 相交,而如果 i , j i,j i,j 相交,则他们到 ( i , j ) (i,j) (i,j) 的时间相同,所以:
i b i = j a i \dfrac{i}{b_i}=\frac{j}{a_i} bii=aij
分子分母交叉相乘得:
i × a i = j × b i i \times a_i=j \times b_i i×ai=j×bi
所以我们可以用 map
维护每个
i
×
a
i
i \times a_i
i×ai 的数量,统计答案时加上
m
p
[
j
×
b
i
]
mp[j \times b_i]
mp[j×bi] 的值,注意
a
i
a_i
ai 为
0
0
0 的情况。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 5;
int n, m, a[N], b[N];
unordered_map <int, int> mp;
signed main(){
cin >> n >> m;
for(int i = 1; i <= n; i ++){
cin >> a[i];
if(a[i] != 0){
mp[i * a[i]] ++;
}
}
int cnt = 0;
for(int i = 1; i <= m; i ++){
cin >> b[i];
cnt += mp[i * b[i]];
}
cout << cnt;
return 0;
}