CodeForces - 1549F1 Gregor and the Odd Cows (Easy)(几何+数论)
題目鏈接:點擊查看
題目大意:給出二維平面上的 nnn 個點,任意選擇出三個點可以構成一個三角形,現在問滿足下面條件的三角形的個數:
其中所有坐標點的 xxx 和 yyy 都是偶數
題目分析:因為所有坐標點都是偶數,所以先猜一波任意三個點都是滿足第一個條件的,也就是圍成的三角形面積一定是偶數。
所以現在問題就轉換為了,如何求解滿足第二個條件的三角形的個數。賽中經隊友提醒,得知了“皮克定理”這一關鍵的結論,即 S=a+b2?1S=a+\frac{b}{2}-1S=a+2b??1,其中 SSS 為三角形的面積,aaa 為三角形內部的點數,bbb 為三角形邊界上的點數。bbb 非常好求,每條邊上的答案就是 gcd?(dx,dy)+1\gcd(dx,dy)+1gcd(dx,dy)+1,放在三角形上就是 gcd?(∣x1?x2∣,∣y1?y2∣)+gcd?(∣x1?x3∣,∣y1?y3∣)+gcd?(∣x3?x2∣,∣y3?y2∣)+3?3\gcd(|x1-x2|,|y1-y2|)+\gcd(|x1-x3|,|y1-y3|)+\gcd(|x3-x2|,|y3-y2|)+3-3gcd(∣x1?x2∣,∣y1?y2∣)+gcd(∣x1?x3∣,∣y1?y3∣)+gcd(∣x3?x2∣,∣y3?y2∣)+3?3,因為三個頂點分別計算了兩次,所以減去三之后就是這個答案了
皮克定理移項之后得到 a=b2?1?Sa=\frac{b}{2}-1-Sa=2b??1?S,如果 aaa 想要為奇數,那么 a+1=b2?Sa+1=\frac{b}{2}-Sa+1=2b??S 需要是偶數,因為上面已經保證了 SSS 是偶數,所以現在只需要保證 b2\frac{b}{2}2b? 是偶數
所以問題轉換為了,有 nnn 個點,任意兩個點之間的邊權為 gcd(dx,dy)/2gcd(dx,dy)/2gcd(dx,dy)/2,現在要求滿足條件的三元環個數,需要滿足三條邊權為:
然后到這里就尬住了,比賽時以為是什么典中典的三元環計數問題,就下班了
第二天看了題解發現,邊權和坐標有著密切的聯系,又因為每個點的坐標都是偶數,所以我們不妨一開始就將坐標除以二
然后我們就很神奇的發現,一共就只有四類點了,分別是 xxx 和 yyy 分別取 000 或 111 的時候。這是點權,邊權的話當且僅當 x1==x2x1==x2x1==x2 and y1==y2y1==y2y1==y2 時,原先點的 gcd?\gcdgcd 才是偶數,其他情況都是奇數
從頭開始再推一遍,發現我們之前的得到的結論沒有變!所以 n3n^3n3 去枚舉計數就好了
你說 n=6000n=6000n=6000?不不,現在的 nnn 實質上只有 444 種情況,用組合數學統計一下答案就好了
代碼:
// 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 eveneven+=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)(几何+数论)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU多校4 - 6989 Didn‘t
- 下一篇: 2021牛客多校6 - Hopping