搜到的题解我一直读不懂…断断续续做了几天之后决定自己写一篇。
首先,有一个暴力的做法:先固定三角形最左最上方的点,然后依次枚举另外两个点,枚举时保证三点不共线。
这是一个的做法。显然会。
尝试用组合计数的知识解决这个问题:用组合数算出选三个不同点的方案数,三点在同一行或同一列的方案数,三点在同一斜线上的方案数。答案就是。
后面的内容将会按照如图所示的坐标系来描述。请先尝试适应这种坐标系表示方法(横纵坐标的方向,的意义)。(我知道图太丑)
注意 只是格子的数量。可选的点一共有个。
计算:
显然是在个元素中任选个的组合数,即
计算:
每行都有种方案在同一行共线,每列都有种方案在同一列共线。
因此
虽然今天不是愚人节(至少我写这个的时候不是),但是在继续下去算之前,我们再讨论另外一种直接计算的方案。这是我第一次写这道题时用的计算方法。(其实把上面的化简也能得到下面的结果,但我只是提供多一种思路吧…)
当然,如果你已经因为做这道题搞得头昏脑涨,然后再来看这篇题解,那就可以跳过这部分,先看如何算。
受前面暴力做法的启发(但并不完全和它相同),我们可以发现就等于其中表示以为最上最左的顶点,且三点不在同一行或者同一列共线(可能在同一条斜线上共线)的方案数。
为了方便叙述,我们在这里设。因此共有个点可以作为三角形的顶点。
考虑如何计算,设的坐标为,另外两个点为,显然有这样几种情况:
1.与在同一行上,在它们的下方。如下图所示。红点为, 可以在所有的绿点中选择(有个),可以在所有的棕点中选择(有)个。共有种方案。
可能你会问,如果是与在同一行,在它们的下面呢?需不需要把这个方案数乘以?
不需要。因为我们计算的是选点的方案数。这里的指代的是其中的一个点,指代的是另外一个点。它们的方案数与排列无关。选择的顶点情况一样就应该被认作是同一种方法。
2.在的正下方,在的斜下方。
为什么不能与在同一行呢?因为这样会和第一种情况有重复。
这样有种选法,有种选法。
共有种选法
3.都在斜下方。
有种选法,有种选法。
共有种选法。注意要除以,因为同一种搭配算了两次。
这就是的算法了。时间复杂度为。它很优秀,可惜极限情况下还是会。
在上面的讨论里,我们发现:
最后的答案就是:
不急,我们一部分一部分搞定。
设
则
先化简:
再化简:
根据平方和的求和公式:,有
最后化简:
同样地,由平方和求和公式和等差数列求和公式:
最后,我们就可以计算出了(注意最后一行是加号不是等号):
然后其实已经没有必要再化简了。
好,无论以哪种方法,我们已经计算出来了。
接下来计算。
计算:
计算是一件很麻烦的事情。我们可以计算出每条非水平非直线上的点数。如果这个点数为,那么在这条斜线上共线的方案数就是现在的问题是,如何计算每条直线的。
为了方便叙述,我们还是设。所以共有个点可以作为三角形的顶点。同时,我们先算左上—右下方向的斜线对答案的贡献。由对称性可知,右上—左下方向的斜线对答案的贡献和它是相同的。
引理
平面直角坐标系上的点与连线上的整数点共有个。()
证明(参考了这里)
设。
已知连线上的点必定满足
即
由的最大性可知,
(假设,那么,,显然会有更大的公约数,而不是。产生矛盾,所以假设不成立)
意即,互质,,所以不为整数。
要使得为整数,首先要满足为内的整数,并且。所以必须为的整数倍。又因为,所以内有个整数,满足 。(这个整数分别是,可以写成的形式)。
证毕。
从上面的引理可知,若以为右下端点:以为左上端点的线段上有个整点,以为左上端点的线段上有个整点,…,以为左上端点的线段上有个端点。
我们设表示大小为的点阵里,有多少组三点共线且包含了左上角。为什么要这么算呢?因为只要能算出来大小的点阵包含了左上角的的三点共线组数,我们就能算出来包含了右下角、左下角、右上角的——由于对称性,它们的答案是一样的。
已知当前计算的三点包含了左上角[ 假设是而不是 ] 。左上—右下走向的共线的三点里一定有一个在最右下方。我们以最右下方的这个点为分类标准,依次统计。这样就能不重不漏。
那么,确定了最左上方和最右下方的点,与这两个点构成三点共线的组数就可以由中间那个点唯一确定了。
若最右下方的点坐标为,它和之间有个整点可以做“三点共线”中的第三点。因此以为右下端点,对统计的贡献就是
因此有递推公式:
上面仅仅统计了包含这个点的左上—右下走向共线的三点数。如何由此得到整个问题的答案?
由对称性我们可以知道,还表示大小为的点阵中,以为最右下点的左上—右下走向的共线的三点数。如果有左上—右下走向的三点,它们最右下的点不同,说明这三点是不可能相同的。
也就是说,的点阵中,所有左上—右下走向的三点共线方案数为,其中
最后做一个前缀和
终于可以得到
然后回顾之前的内容,整个问题就解决了。
代码实现应该算简单,我就不放了。