P3166 数三角形
P3166 数三角形
过的第一篇紫题,特此发一篇博客庆祝一下
思路
obviously,总体思路大概为这样的:【三角形数量】等于【任选三个点的方案数】减去【三点共线方案数】
因为是一个N · M的方格,所以共有(n+1)·(m+1)的点,那么由组合数可得【三个点的方案数】为$C_{(n+1)(m+1)}^3$
so现在我们只需要知道三点共线的方案数即可
【三点共线的方案数】等于【横着的】加上【竖着的】加上【斜着的】
接下来我们就要分类讨论了:
【横着的】:
指三点所在直线平行于 x 轴。共有 m+1 条横线,每条横线上有 n+1 个点,从这 n+1 个点中选取 3 个,方案数为 (m+1)$C_{n+1}^3$
那么同理,【竖着的】指三点所在直线平行于 y 轴,方案数为(n+1)$C_{m+1}^3$
最难的是【斜着的】,斜着的直线按斜率正负分为两种,并且这两种方案数是相等(obviously)所以,我们只需要计算出斜率为正的方案数,再乘2就完了(好像很简单)
方便起见,我们将斜率为正的方案数记为ans
解决
通过观察可以发现一个小小的结论:
假设网格中AB平行于底边x轴,长度为i,BC平行于侧边y轴,长度为j,那么AC上的整点数为gcd(i , j) + 1(这个很好发现)
那么我们就可以枚举两点横坐标差 i,纵坐标差 j,则两点连线上的整点数量为 gcd(i , j) + 1不算两端点自身的话有 gcd(i , j) − 1 个)
对于每组横坐标差 i,纵坐标差 j 的点对,我们先选取两端点,再在他俩之间的 gcd(i , j) - 1 个点中任选一个作为第三个点,方案数为 gcd(i , j) - 1
每组点对可以有 gcd(i , j) - 1 种方案,像这样横坐标差 i,纵坐标差 j 的点对共有 (n - i + 1)(m - j + 1) 个,故可以枚举 i , j 计算:$\sum_{i=1}^n\sum_{j=1}^m$(n - i + 1)(m - j + 1)(gcd(i , j) - 1 )
当然,直接计算这个式子时间复杂度为O(nm)=O($n^2$),考虑gcd的话甚至是O($n^2\log n$)(但是对于这题还是绰绰有余的,毕竟数据太水了)
****看了题解后发现竟然还有O(n)的方法,不过本人太菜了,没有看懂(蒟蒻)