CF1548D1. Gregor and the Odd Cows (Easy)
题意:
给出平面上
n
n
n个点,求选三个点构成的三角形满足面积是整数,且三角形内部的整数点的个数是奇数的个数。
其中
x
,
y
x,y
x,y均为偶数,且不存在任意三点共线。
思路:
由pick定理可知:
S
=
a
+
b
2
−
1
S=a+\cfrac{b}{2}-1
S=a+2b−1,其中
a
a
a为三角形内部整点数,
b
b
b为三角形边上整点数。
由于
x
,
y
x,y
x,y均为偶数,所以三角形面积
S
S
S也肯定为偶数。所以可得
2
S
=
2
a
+
b
−
1
2S=2a+b-1
2S=2a+b−1,又因为
a
a
a是奇数,所以
2
S
≡
b
≡
0
m
o
d
4
2S\equiv b\equiv0\mod 4
2S≡b≡0mod4。
这样就变成了求
b
≡
0
m
o
d
4
b\equiv0\mod 4
b≡0mod4的个数了。我们又已知
(
x
1
,
y
1
)
(x_1,y_1)
(x1,y1)和
(
x
2
,
y
2
)
(x_2,y_2)
(x2,y2)上的整数点个数为
gcd
(
∣
x
1
−
x
2
∣
,
∣
y
1
−
y
2
∣
)
\gcd(|x_1-x_2|,|y_1-y_2|)
gcd(∣x1−x2∣,∣y1−y2∣)。并且由于
x
,
y
x,y
x,y均为偶数,所以
gcd
\gcd
gcd肯定也是偶数。
由于之前的分析,我们只用考虑
gcd
m
o
d
4
\gcd\mod 4
gcdmod4之后的情况。
- gcd ≡ 0 m o d 4 \gcd\equiv 0\mod 4 gcd≡0mod4,当且仅当 x 1 ≡ x 2 m o d 4 , y 1 ≡ y 2 m o d 4 x_1\equiv x_2\mod 4,y_1\equiv y_2\mod 4 x1≡x2mod4,y1≡y2mod4的时候成立。
- gcd ≡ 2 m o d 4 \gcd\equiv 2\mod 4 gcd≡2mod4,其余的情况。
要使
b
≡
0
m
o
d
4
b\equiv0\mod4
b≡0mod4成立,要么选
3
3
3个点满足三条边的
gcd
≡
0
m
o
d
4
\gcd\equiv0\mod 4
gcd≡0mod4成立;要么满足一条边
gcd
≡
0
m
o
d
4
\gcd\equiv0\mod4
gcd≡0mod4,其余两条边
gcd
≡
2
m
o
d
4
\gcd\equiv2\mod4
gcd≡2mod4成立。
我们发现只要将原来的点变成
(
x
m
o
d
4
,
y
m
o
d
4
)
(x\mod 4,y\mod4)
(xmod4,ymod4)之后再考虑选点就行了。
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define int long long
#define mp make_pair
#define pb push_back
#define ls x<<1
#define rs x<<1|1
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define cl(x,y) memset(x,y,sizeof(x))
#define nxtp(a,n) next_permutation(a+1,a+n+1)
#define mem(x,y,n) memset(x,y,sizeof(int)*(n+5))
const int N=1e6+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double pi=acos(-1);
const double INF=1e18;
using namespace std;
int a[4][4];
signed main()
{
#ifdef ChuTian
clock_t stTime = clock();
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,i,j,k,l;;
cin>>n;
for(i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
a[x%4][y%4]++;
}
int ans=0;
for(i=0;i<=2;i+=2)
for(j=0;j<=2;j+=2)
{
int v=a[i][j];
ans+=v*(v-1)*(v-2)/6;
for(k=0;k<=2;k+=2)
for(l=0;l<=2;l+=2)
{
int w=a[k][l];
if(k==i && l==j)
continue;
ans+=v*w*(w-1)/2;
}
}
cout<<ans<<endl;
#ifdef ChuTian
cerr << "Time Used:" << clock() - stTime << "ms" <<endl;
#endif
return 0;
}