解题思路

先看到第一个条件 ai+aj0 (mod x)a_i + a_j \equiv 0\ ({\rm mod}\ x),可以推出如下性质:

ai mod x+aj mod x0 (mod x)a_i \ {\rm mod} \ x + a_j \ {\rm mod} \ x \equiv 0 \ ({\rm mod} \ x)

这样我们就可以在范围为 0x10 \sim x - 1 中查找满足条件的值,及对于每一个 aia_i,符合条件的 aja_j

(x(ai mod x)) mod x(x - (a_i \ \rm mod \ x)) \ \rm mod \ x

而对于条件 aiaj0 (mod y)a_i - a_j \equiv 0\ ({\rm mod}\ y),只需要让 aia_iaja_j 同余即可。即:

aiaj (mod y)a_i \equiv a_j \ (\rm mod \ y)

我们只需要用 map 存储每个元素的两个条件,从而达到近似为 O(1)O(1) 的查询。

AC Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void solve()
{
int res = 0;
int n, x, y; cin >> n >> x >> y;

for (int i = 1; i <= n; i ++)
cin >> a[i];

map<PII, int> mp; // #define PII pair<int, int>

for (int i = 1; i <= n; i ++)
{
int dx = a[i] % x, dy = a[i] % y;
res += mp[{(x - dx) % x, dy}];
mp[{dx, dy}] ++;
}
cout << res << '\n';
}