题目描述
平面直角坐标系上有 n+mn + mn+m 个点,其中:
- 有 nnn 个 A\rm AA 类点,它们在初始时依次位于位置 (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)。
- 有 mmm 个 B\rm BB 类点,它们在初始时依次位于位置 (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, BA,B 类点同时开始运动。具体地:
- 对于第 iii 个 A\rm AA 类点,其以 aia_iai 个单位长度每秒的速度向上(即 yyy 轴正方向)匀速运动。特别地,若 ai=0a_i = 0ai=0,则该点始终保持静止。
- 对于第 iii 个 B\rm BB 类点,其以 bib_ibi 个单位长度每秒的速度向右(即 xxx 轴正方向)匀速运动。特别地,若 bi=0b_i = 0bi=0,则该点始终保持静止。
你能否帮小 T 解决一个简单的问题:求出有多少点对会在某个时刻相遇,即它们在某一刻共点。
分析
对于两个点如果同为 A\rm AA 类点,或同为 B\rm BB 类点,他们是不会相交的,因为他们的移动方向是不同的,我们假设相交的点编号为 i,ji,ji,j,可以发现他们必然在 (i,j)(i,j)(i,j) 相交,而如果 i,ji,ji,j 相交,则他们到 (i,j)(i,j)(i,j) 的时间相同,所以:
ibi=jai\dfrac{i}{b_i}=\frac{j}{a_i}bii=aij
分子分母交叉相乘得:
i×ai=j×bii \times a_i=j \times b_ii×ai=j×bi
所以我们可以用 map
维护每个 i×aii \times a_ii×ai 的数量,统计答案时加上 mp[j×bi]mp[j \times b_i]mp[j×bi] 的值,注意 aia_iai 为 000 的情况。
代码
#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;
}