#几何 #枚举
## 题目大意
给你 $n$ 个点,现在要你选择其中的三个点组成一个直角三角形,并求出所有可能组成的三角形的面积之和的两倍对 $10^9+7$ 取模后的值。
## 分析
首先,$n\le 10^5$,我们不可能枚举所有的组合。但是,这题明确告诉了我们构造出来的必须是直角三角形,因此肯定有两条边是平行于 $x$ 轴或 $y$ 轴的,而这题值域范围特别小,只有正负 $10^4$,因此我们就可以开多个 [[vector]] 来记录同样的 $x$ 或 $y$ 可以对应哪些不同的 $y$ 或 $x$,然后再枚举平行的点。
但是三重循环还是会超时,我们则需要考虑答案的贡献。对于一个平行于 $x$ 轴的点,与当前点 $y$ 坐标的绝对差值就可以看做三角形的底;另一个平行于 $y$ 轴的点距离当前点 $x$ 坐标的绝对差值,就可以看做不同长度的三角形的高。我们就拿每一个底配所有的高。因此答案就是所有底的长度和乘上所有高的长度和。
**注意:**`long long` 开了没,负数坐标有没有特殊处理,有没有取模?
## 代码
```kotlin
import java.util.*
import kotlin.math.abs
val cin = Scanner(System.`in`)
const val mod = 1e9.toInt() + 7
val n = cin.nextInt()
val x = IntArray(n + 1)
val y = IntArray(n + 1)
val xy = Array(2e4.toInt() + 5) { ArrayList<Int>() }
val yx = Array(2e4.toInt() + 5) { ArrayList<Int>() }
var ans = 0L
fun main() {
for (i in 1..n) {
x[i] = cin.nextInt() + 1e4.toInt()
y[i] = cin.nextInt() + 1e4.toInt()
xy[x[i]].add(y[i])
yx[y[i]].add(x[i])
}
for (i in 1..n) {
var s1 = 0L
var s2 = 0L
for (j in xy[x[i]]) {
s1 += abs(y[i] - j)
}
for (j in yx[y[i]]) {
s2 += abs(x[i] - j)
}
ans = (ans + s1 * s2) % mod
}
println(ans)
}
```