传送门
题目描述
honoka最近在研究三角形计数问题。 她认为,满足以下三个条件的三角形是“好三角形”。
三角形的三个顶点均为格点,即横坐标和纵坐标均为整数。
三角形的面积为 。
三角形至少有一条边和 轴或 轴平行。 honoka想知道,在平面中选取一个大小为 的矩形格点阵,可以找到多少个不同的“好三角形”?由于答案可能过大,请对 取模。
输入描述:
两个正整数和
(
2
≤
n
,
m
≤
1
0
9
)
( 2\ ≤n,m≤10^9)
( 2 ≤ n , m ≤ 1 0 9 )
输出描述:
面积为1的格点三角形的数量,对
1
0
9
+
7
10^9+7
1 0 9 + 7 取模的结果。
输入
2 3 100 100
输出
6 7683984
说明
格点如下: * * * * * *
不妨设左下角坐标为(1,1),右上角坐标为到(3,2)。 那么三点坐标可选: (1,1)(1,2)(3,1) (1,1)(1,2)(3,2) (1,1)(2,2)(3,1) (1,1)(3,1)(3,2) (1,2)(2,1)(3,2) (1,2)(3,1)(3,2) 所以共有6个。
题解
可以把面积为
1
1
1 的“好三角形”分为两类分开统计:两条边和两个坐标轴平行;只有一条边和某个坐标轴平行。 对于第一种情况,一定是
1
∗
2
1*2
1 ∗ 2 或者
2
∗
1
2*1
2 ∗ 1 的形式,一个
1
∗
2
1*2
1 ∗ 2 的矩形中含有
4
4
4 个不同的三角形。总数是
4
∗
(
(
n
−
2
)
∗
(
m
−
1
)
+
(
m
−
2
)
∗
(
n
−
1
)
)
4*((n-2)*(m-1)+(m-2)*(n-1))
4 ∗ ( ( n − 2 ) ∗ ( m − 1 ) + ( m − 2 ) ∗ ( n − 1 ) )
对于第二种情况,可以分别统计底边为
2
2
2 、高为
1
1
1 和底边为
1
1
1 、高为
2
2
2 的情况。要注意底边靠近边界时的特殊讨论。
①对于底边为
2
2
2 ,高为
1
1
1 的情况: 若底边和
x
x
x 轴平行,那么底边横向移动(指
x
x
x 轴水平移动,下同)有
n
−
2
n-2
n − 2 种可能,“对点”(指底边相对的点)的某一面选择有
n
−
2
n-2
n − 2 种可能(某一面选择,指的是底边固定的情况,对点在一条直线上移动所做出的选择),而底边纵向移动有
m
m
m 种情况,其中有
(
m
−
2
)
(m−2)
( m − 2 ) 种情况对点可以选择两个面,
2
2
2 种情况对点只能选择一个面(当底边移动到格点阵边界的时候)。因此纵向移动折合为
2
∗
(
m
−
2
)
+
2
2*(m-2)+2
2 ∗ ( m − 2 ) + 2 ,即
2
∗
(
m
−
1
)
2*(m-1)
2 ∗ ( m − 1 ) 以上可计算为
2
∗
(
m
−
1
)
∗
(
n
−
2
)
∗
(
n
−
2
)
2*(m-1)*(n-2)*(n-2)
2 ∗ ( m − 1 ) ∗ ( n − 2 ) ∗ ( n − 2 ) 若底边和
y
y
y 轴平行,同理可推出
2
∗
(
n
−
1
)
∗
(
m
−
2
)
∗
(
m
−
2
)
2*(n-1)*(m-2)*(m-2)
2 ∗ ( n − 1 ) ∗ ( m − 2 ) ∗ ( m − 2 )
②对于底边为
1
1
1 ,高为
2
2
2 的情况,推理方法和上面类似,请选手们自行推理。
参
考
c
f
难
度
分
:
1500
参考cf难度分:1500
参 考 c f 难 度 分 : 1 5 0 0
最
后
得
到
三
类
分
别
为
:
最后得到三类分别为:
最 后 得 到 三 类 分 别 为 :
l
l
ll
l l
a
n
s
1
=
4
∗
(
(
n
−
2
)
∗
(
m
−
1
)
+
(
m
−
2
)
∗
(
n
−
1
)
)
;
ans1 = 4 * ((n - 2) * (m - 1) + (m - 2) * (n - 1));
a n s 1 = 4 ∗ ( ( n − 2 ) ∗ ( m − 1 ) + ( m − 2 ) ∗ ( n − 1 ) ) ;
l
l
ll
l l
a
n
s
2
=
2
∗
(
m
−
1
)
∗
(
n
−
2
)
∗
(
n
−
2
)
+
2
∗
(
n
−
1
)
∗
(
m
−
2
)
∗
(
m
−
2
)
;
ans2 = 2 * (m - 1) * (n - 2) * (n - 2) \\\ \ \ \ \ \ \ \ \ \ \ \ \ \ + 2 * (n - 1) * (m - 2) * (m - 2);
a n s 2 = 2 ∗ ( m − 1 ) ∗ ( n − 2 ) ∗ ( n − 2 ) + 2 ∗ ( n − 1 ) ∗ ( m − 2 ) ∗ ( m − 2 ) ;
l
l
ll
l l
a
n
s
3
=
(
n
−
1
)
∗
(
n
−
2
)
∗
(
2
∗
(
m
−
4
)
+
4
)
+
(
m
−
1
)
∗
(
m
−
2
)
∗
(
2
∗
(
n
−
4
)
+
4
)
;
ans3 = (n - 1) * (n - 2) * (2 * (m - 4) + 4) \\\ \ \ \ \ \ \ \ \ \ \ \ + (m - 1) * (m - 2) * (2 * (n - 4) + 4);
a n s 3 = ( n − 1 ) ∗ ( n − 2 ) ∗ ( 2 ∗ ( m − 4 ) + 4 ) + ( m − 1 ) ∗ ( m − 2 ) ∗ ( 2 ∗ ( n − 4 ) + 4 ) ;
AC-Code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll M = 1e9 + 7 ;
ll ans = 0 , n, m;
int main ( ) {
cin >> n >> m;
ans + = ( ( ( 2 * m * n - 3 * n - 3 * m + 4 ) % M) * ( ( 2 * m + 2 * n - 4 ) % M) ) % M;
cout << ans;
}