好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:
题目描述
给定一个 n×m 的网格(注意:题目输入是 m 和 n,但通常理解网格为 n 行 m 列,格点有 (n+1) 行 (m+1) 列),请计算三点都在格点上的三角形共有多少个。三角形的三点不能共线。
示例:下图是一个 4×4 网格(即 n=4,m=4,格点矩阵为 5×5)上的一个三角形。

(注:此处原题有图,表示三个格点构成三角形)
输入格式
输入一行,包含两个空格分隔的正整数 m 和 n。
注意:这里 m 和 n 表示横向 m 段、纵向 n 段,因此格点矩阵为 (m+1)×(n+1) 个点。
输出格式
输出一个正整数,为所求三角形数量。
样例
样例输入 1
2 2
样例输出 1
76
样例解释 1
m=2,n=2,格点为 (3×3) 共 9 个点。
三角形总数 = 任选三点 - 三点共线的方案数。
-
任选三点:C(9,3)=84;
-
三点共线的情况:
- 水平线:3 条横线,每条 3 个点,共 3×C(3,3)=3×1=3;
- 竖直线:3 条竖线,每条 3 个点,共 3×1=3;
- 斜线(斜率正负):
- 主对角线(从 (0,0) 到 (2,2)):3个点,C(3,3)=1;
- 反对角线(从 (0,2) 到 (2,0)):3个点,C(3,3)=1;
- 其他斜线需要计算:例如斜率 1/2 或 2/1 在这个小网格中不存在超过2个格点,所以不考虑。
所以共线数 =3+3+1+1=8。
三角形数 =84−8=76。
数据范围
对于所有数据,1≤m,n≤1000。
注意:答案可能很大,需要使用 64 位整数(C++ 中用 long long)。
时空限制
- 时间:1000 ms
- 内存:524288 KB
提示
- 总点数为 (m+1)×(n+1);
- 任选三点方案数为 C(m+1)(n+1)3;
- 三点共线情况包括:
- 水平线:(n+1)×Cm+13;
- 竖直线:(m+1)×Cn+13;
- 斜线(斜率不为 0 或无穷):枚举向量 (dx,dy) 且 gcd(dx,dy)=1,线段两端在网格内,中间有 k 个格点,这样的线段有 (m−dx+1)×(n−dy+1)×2(考虑正负斜率),每个线段贡献 Ck+13。
- 斜线枚举 dx,dy 从 1 到 m,n,复杂度 O(mn) 可接受。