CodeForces - 1549F1 Gregor and the Odd Cows (Easy)(几何+数论)

Posted Frozen_Guardian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1549F1 Gregor and the Odd Cows (Easy)(几何+数论)相关的知识,希望对你有一定的参考价值。

题目链接:点击查看

题目大意:给出二维平面上的 n n n 个点,任意选择出三个点可以构成一个三角形,现在问满足下面条件的三角形的个数:

  1. 三角形面积为整数
  2. 三角形包含的(不包括边界)整数点为奇数

其中所有坐标点的 x x x y y y 都是偶数

题目分析:因为所有坐标点都是偶数,所以先猜一波任意三个点都是满足第一个条件的,也就是围成的三角形面积一定是偶数。

所以现在问题就转换为了,如何求解满足第二个条件的三角形的个数。赛中经队友提醒,得知了“皮克定理”这一关键的结论,即 S = a + b 2 − 1 S=a+\\frac{b}{2}-1 S=a+2b1,其中 S S S 为三角形的面积, a a a 为三角形内部的点数, b b b 为三角形边界上的点数。 b b b 非常好求,每条边上的答案就是 gcd ⁡ ( d x , d y ) + 1 \\gcd(dx,dy)+1 gcd(dx,dy)+1,放在三角形上就是 gcd ⁡ ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ∣ ) + gcd ⁡ ( ∣ x 1 − x 3 ∣ , ∣ y 1 − y 3 ∣ ) + gcd ⁡ ( ∣ x 3 − x 2 ∣ , ∣ y 3 − y 2 ∣ ) + 3 − 3 \\gcd(|x1-x2|,|y1-y2|)+\\gcd(|x1-x3|,|y1-y3|)+\\gcd(|x3-x2|,|y3-y2|)+3-3 gcd(x1x2,y1y2)+gcd(x1x3,y1y3)+gcd(x3x2,y3y2)+33,因为三个顶点分别计算了两次,所以减去三之后就是这个答案了

皮克定理移项之后得到 a = b 2 − 1 − S a=\\frac{b}{2}-1-S a=2b1S,如果 a a a 想要为奇数,那么 a + 1 = b 2 − S a+1=\\frac{b}{2}-S a+1=2bS 需要是偶数,因为上面已经保证了 S S S 是偶数,所以现在只需要保证 b 2 \\frac{b}{2} 2b 是偶数

所以问题转换为了,有 n n n 个点,任意两个点之间的边权为 g c d ( d x , d y ) / 2 gcd(dx,dy)/2 gcd(dx,dy)/2,现在要求满足条件的三元环个数,需要满足三条边权为:

  1. 奇数、奇数、偶数
  2. 偶数、偶数、偶数

然后到这里就尬住了,比赛时以为是什么典中典的三元环计数问题,就下班了

第二天看了题解发现,边权和坐标有着密切的联系,又因为每个点的坐标都是偶数,所以我们不妨一开始就将坐标除以二

然后我们就很神奇的发现,一共就只有四类点了,分别是 x x x y y y 分别取 0 0 0 1 1 1 的时候。这是点权,边权的话当且仅当 x 1 = = x 2 x1==x2 x1==x2 and y 1 = = y 2 y1==y2 y1==y2 时,原先点的 gcd ⁡ \\gcd gcd 才是偶数,其他情况都是奇数

从头开始再推一遍,发现我们之前的得到的结论没有变!所以 n 3 n^3 n3 去枚举计数就好了

你说 n = 6000 n=6000 n=6000?不不,现在的 n n n 实质上只有 4 4 4 种情况,用组合数学统计一下答案就好了

代码:

// Problem: F1. Gregor and the Odd Cows (Easy)
// Contest: Codeforces - Codeforces Round #736 (Div. 2)
// URL: https://codeforces.com/contest/1549/problem/F1
// Memory Limit: 256 MB
// Time Limit: 6000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
	T f=1;x=0;
	char ch=getchar();
	while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	x*=f;
}
template<typename T>
inline void write(T x)
{
	if(x<0){x=~(x-1);putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
LL cnt[2][2];
LL C(int n,int m) {
	if(m==1) {
		return n;
	} else if(m==2) {
		return 1LL*n*(n-1)/2;
	} else if(m==3) {
		return 1LL*n*(n-1)*(n-2)/6;
	}
}
int cal(int x1,int y1,int x2,int y2) {
	if(x1==x2&&y1==y2) {
		return true;
	} else {
		return false;
	}
}
int main()
{
#ifndef ONLINE_JUDGE
//	freopen("data.in.txt","r",stdin);
//	freopen("data.out.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	int n;
	read(n);
	for(int i=1;i<=n;i++) {
		int x,y;
		read(x),read(y);
		cnt[x%4/2][y%4/2]++;
	}
	LL ans=0;
	for(int s1=0;s1<4;s1++) {
		for(int s2=s1;s2<4;s2++) {
			for(int s3=s2;s3<4;s3++) {
				int x1=s1/2,y1=s1%2;
				int x2=s2/2,y2=s2%2;
				int x3=s3/2,y3=s3%2;
				int even=0;
				//2odds + 1even or 3 even
				even+=cal(x1,y1,x2,y2);
				even+=cal(x1,y1,x3,y3);
				even+=cal(x2,y2,x3,y3);
				if(even==2||even==0) {
					continue;
				}
				if(s1==s2&&s2==s3) {
					ans+=C(cnt[x1][y1],3);
				} else if(s1==s2) {
					ans+=C(cnt[x1][y1],2)*cnt[x3][y3];
				} else if(s2==s3) {
					ans+=C(cnt[x2][y2],2)*cnt[x1][y1];
				} else if(s1==s3) {
					ans+=C(cnt[x1][y1],2)*cnt[x2][y2];
				} else {
					ans+=cnt[x1][y1]*cnt[x2][y2]*cnt[x3][y3];
				}
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}

以上是关于CodeForces - 1549F1 Gregor and the Odd Cows (Easy)(几何+数论)的主要内容,如果未能解决你的问题,请参考以下文章

codeforces上怎么看测试数据

如何看codeforces做了多少题

codeforces上怎么看测试数据

codeforces比赛后怎么看题解和答案

codeforces是啥?

codeforces Codeforces 650A Watchmen