F Triangles
匹克定理:
若多边形顶点坐标都为整点,令其面积为
S
S
S,其内部整点数为
n
e
ne
ne,其边界上的整点数为
w
a
wa
wa,则有
S
=
n
e
+
w
a
/
2
−
1
S=ne+wa/2-1
S=ne+wa/2−1
设三个点为
(
a
,
0
)
,
(
0
,
b
)
,
(
w
,
c
)
(a,0),(0,b),(w,c)
(a,0),(0,b),(w,c),其中
c
>
=
b
c>=b
c>=b,对与
c
<
b
c<b
c<b由对称性可得。对于选其它不同边上的点可转换为同样的情况。
根据匹克定理,有
2
∗
n
e
=
2
∗
S
−
w
a
+
2
<
=
2
∗
k
2*ne=2*S-wa+2<=2*k
2∗ne=2∗S−wa+2<=2∗k
其中
2
∗
S
=
a
∗
(
c
−
b
)
+
b
∗
w
2*S=a*(c-b)+b*w
2∗S=a∗(c−b)+b∗w(根据多边形面积公式可得)。
w
a
=
(
w
−
a
,
c
)
+
(
a
,
b
)
+
(
c
−
b
,
w
)
wa=(w-a,c)+(a,b)+(c-b,w)
wa=(w−a,c)+(a,b)+(c−b,w)。
(
a
,
b
)
(a,b)
(a,b)表示
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)。
枚举
a
a
a和
c
−
b
c-b
c−b。
则有:
a
∗
(
c
−
b
)
+
w
∗
b
−
(
w
−
a
,
c
)
−
(
a
,
b
)
−
(
c
−
b
,
w
)
+
2
<
=
2
∗
k
a*(c-b)+w*b-(w-a,c)-(a,b)-(c-b,w)+2<=2*k
a∗(c−b)+w∗b−(w−a,c)−(a,b)−(c−b,w)+2<=2∗k
==>
w
∗
b
−
(
w
−
a
,
c
)
−
(
a
,
b
)
<
=
2
∗
k
−
a
∗
(
c
−
b
)
+
(
c
−
b
,
w
)
−
2
w*b-(w-a,c)-(a,b)<=2*k-a*(c-b)+(c-b,w)-2
w∗b−(w−a,c)−(a,b)<=2∗k−a∗(c−b)+(c−b,w)−2
令右式为
R
R
R,左式为
L
L
L,由于
(
w
−
a
,
c
)
+
(
a
,
b
)
<
=
w
(w-a,c)+(a,b)<=w
(w−a,c)+(a,b)<=w,
故
w
∗
(
b
−
1
)
<
=
L
<
=
w
∗
b
w*(b-1)<=L<=w*b
w∗(b−1)<=L<=w∗b。
当
b
<
=
R
/
w
b<=R/w
b<=R/w,有
L
<
=
b
∗
w
<
=
R
L<=b*w<=R
L<=b∗w<=R,不等式恒成立。
当
b
>
R
/
w
+
1
b>R/w+1
b>R/w+1,有
L
>
=
(
b
−
1
)
∗
w
>
R
L>=(b-1)*w>R
L>=(b−1)∗w>R,不等式恒不成立。
当
R
/
w
<
b
<
=
R
/
w
+
1
R/w<b<=R/w+1
R/w<b<=R/w+1,将所有值代入不等式判断即可。
又
R
>
=
w
∗
(
b
−
1
)
且
b
>
=
1
R>=w*(b-1)且b>=1
R>=w∗(b−1)且b>=1,故
R
>
=
0
R>=0
R>=0
则有
2
∗
k
−
a
∗
(
c
−
b
)
+
(
c
−
b
,
w
)
−
2
>
=
0
2*k-a*(c-b)+(c-b,w)-2>=0
2∗k−a∗(c−b)+(c−b,w)−2>=0,需要枚举的
a
a
a和
c
−
b
c-b
c−b的对数为
M
l
o
g
(
M
)
Mlog(M)
Mlog(M)对
(
M
=
1
e
5
)
(M=1e5)
(M=1e5)。
总时间复杂度为 M l o g ( M ) l o g ( M ) Mlog(M)log(M) Mlog(M)log(M)。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
int h,w,k;
ll solve(int w,int h)
{
ll ans=0;
for(int a=1;a<w;a++)
for(int c_b=0;c_b<h;c_b++)
{
int R=2*k-a*c_b+__gcd(c_b,w)-2;
if(R<0) break;
int low=min(h-1-c_b,R/w);
ans+=c_b==0?low:low*2;
low++;
if(low+c_b<h&&w*low-__gcd(w-a,low+c_b)-__gcd(a,low)<=R)
ans+=c_b==0?1:2;
}
return ans*2;
}
int main()
{
scanf("%d%d%d",&w,&h,&k);
printf("%lld\n",solve(w,h)+solve(h,w));
}