牛客训练~honoka和格点三角形~解题报告

honoka和格点三角形

题目描述:

honoka最近在研究三角形计数问题。
她认为,满足以下三个条件的三角形是“好三角形”。
1.三角形的三个顶点均为格点,即横坐标和纵坐标均为整数。
2.三角形的面积为 。
3.三角形至少有一条边和 轴或 轴平行。
honoka想知道,在平面中选取一个大小为  的矩形格点阵,可以找到多少
不同的“好三角形”?由于答案可能过大,请对 取模

Input:

两个正整数n,m(2 ≤n,m≤109次方)

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的矩形中,
 如果按照小数去解的话,应该有无限个把,所以也做过多分析,但这里需
 要注意一点,他的输入是最大是109次方,这里需要注意(取模)。

思路分析:

这道题重点在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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值