honoka和格点三角形
题目描述:
honoka最近在研究三角形计数问题。
她认为,满足以下三个条件的三角形是“好三角形”。
1.三角形的三个顶点均为格点,即横坐标和纵坐标均为整数。
2.三角形的面积为 。
3.三角形至少有一条边和 轴或 轴平行。
honoka想知道,在平面中选取一个大小为 的矩形格点阵,可以找到多少
不同的“好三角形”?由于答案可能过大,请对 取模
Input:
两个正整数n,m(2 ≤n,m≤10的9次方)
Output:
面积为1的格点三角形的数量,对 10的九次方+7 取模的结果。
Sample Input:
2 3
Sample Output:
6
Sample Input.2:
100 100
Sample Output.2:
7683984
条件分析:
这道题条件很明确一一分析:
1. 面积为1的三角形:这个只要满足底为2与高为1即可或者满足高为2
底为1的三角形即可。
2. 至少有一条边平行于x或者y轴:这里只要以底平行或者高平行即可,
不做过多分析。
3. 都是整数:这个我感觉按题目意思来解,毕竟他给的是m*n的矩形中,
如果按照小数去解的话,应该有无限个把,所以也做过多分析,但这里需
要注意一点,他的输入是最大是10的9次方,这里需要注意(取模)。
思路分析:
这道题重点在m*n的矩形中找到有多少个面积为1的三角形就可以了。
这里mod=10的九次方+7
1. 以底为2的三角形,那么如果以底为2,每一行就有(m-2)个2,
然后在该行距离为1的点都可以构造三角形,就有(n-1)行(因为当到达n
行的时候,顶上没点可取),然后从顶到底也可以以这样方式取,这样就有
d=(n-1)*(m-2)*m*2%mod。
2. 以高为2的三角形,那么如果以高为2,从左到右每一列就有(n-2)个2,
在该列距离为(m-1)行,取一点即可,从右到左也是同理所得这样就有
e=2*(n-2)*n*(m-1)%mod。
3. 以高为1的三角形,那么如果以高为1,从左到右每列就有(n-1)个1,
但是这里不能每列都包括,他只能求(n-2)列,(排除以底为2,高为1
的情况),这里求行也要改变,只能求(m-2)行,然后从右到左也可以,
这样就有
g=2*(n-1)*(n-2)*(m-2)%mod
4. 以底为1的三角形,那么如果以底为1,每一行就有(m-1)个1,则因
要(排除以底为1,高为2的直角三角形情况),所以计算(m-2)行就行
,然后在(n-2)列中取一点即可,从顶到底同理也可以,这样就有
h=2*(m-1)*(m-2)*(n-2)%mod。
5.在将d+g+e+h所有结果的总和取模即可,但是上面只是思路分析,如果
按照上述的方式计算,会导致WA,正确答案看代码,因为数据过大,如果
不将其分开取模,会导致结果变负数 。
代码:
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
using namespace std;
const int c=1000000007;
int main()
{
long long n,m;
scanf("%lld %lld",&n,&m);
long long b=0;
b=(b+2*(m-2)*m%c*(n-1))%c;
b=(b+2*(n-2)*n%c*(m-1))%c;
b=(b+2*(n-1)*(n-2)%c*(m-2))%c;
b=(b+2*(m-1)*(m-2)%c*(n-2))%c;
printf("%lld",b);
}