honoka最近在研究三角形计数问题。
她认为,满足以下三个条件的三角形是“好三角形”。
1.三角形的三个顶点均为格点,即横坐标和纵坐标均为整数。
2.三角形的面积为 1。
3.三角形至少有一条边和 x轴或 y轴平行。
honoka想知道,在平面中选取一个大小为n∗m n*mn∗m的矩形格点阵,可以找到多少个不同的“好三角形”?由于答案可能过大,请对1000000007取模
题意:要使三角形面积为1,则只有底为1、高为2和底为2、高为1两种情况;
可将好三角形分为下面几种情况:
1.两条边均平行x或y轴的;
2.一条边平行x轴,底为2、高为1的;
3.一条边平行x轴,底为1、高为2的;
4.一条边平行y轴,底为2、高为1的;
5.一条边平行y轴,底为1、高为2的;
所以求好三角形的总数即为求各自情况下的好三角形总数:
第一种即以2 * 3点阵为最小单位,每个点阵中有四个好三角形
第二种即求出2 * m点阵中的底为2、高为1的好三角形,再乘上n - 1行,即为总数
第三种即求出3 * m点阵中的底为1、高为2的好三角形,再乘上n - 2行,即为总数
第四、五种同理
对于n * m 点阵中,与x轴平行的底为1的好三角形的方案有(m - 1)* (m - 1) * (n - 2)种,即去掉与xy轴皆平行的好三角形后,能构成底为1、高为2的好三角形有m - 1种,且有m - 1条长度为1的边,剩余情况同理
注:方案数较大,要在每一步计算总数后取模。
#include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <stack> #include <stdio.h> #include <cmath> #include <string.h> #include <vector> #define ll long long #define inf 0x3f3f3f3f using namespace std; const int mod = 1e9 + 7; int main() { ios::sync_with_stdio(false); ll n, m, ans = 0; cin >> n >> m; ans += (n - 1) * (m - 2) * 4 % mod + (n - 2) * (m - 1) * 4 % mod; ans = (ans + 2 * (m - 2) * (n - 1) % mod * (m - 2) % mod + 2 * (n - 2) * (m - 1) % mod * (n - 2) % mod) % mod; ans = (ans + 2 * (m - 1) * (n - 2) % mod * (m - 2) % mod + 2 * (n - 1) * (m - 2) % mod * (n - 2) % mod) % mod; cout << ans << endl; return 0; }