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;
}