bzoj1041 & 洛谷2508 HAOI2008 圓上的整點 數學

題目鏈接:
洛谷2508
bzoj1041

Description
求一個給定的圓(x2+y2=r2)(x^2+y^2=r^2),在圓周上有多少個點的座標是整數。

Input
只有一個正整數n,n<=2000000000n,n<=2000 000 000

Output
整點個數

Sample Input
4
Sample Output
4

首先不難看出最終答案是第一象限的整點數乘4加上四個座標軸上的點。
所以假設x>0,y>0x>0,y>0
移項,得到x2=n2y2=(n+y)(ny)x^2=n^2-y^2=(n+y)(n-y)
關鍵一步:d=gcd(n+y,ny)d=gcd(n+y,n-y)ny=da2,n+y=db2n-y=da^2,n+y=db^2,則a,ba,b互質。
代入,得到x2=d2a2b2x^2=d^2a^2b^2x=dabx=dab
因爲n+y=db2,ny=da2n+y=db^2,n-y=da^2,所以
兩式相減有2y=d(b2a2)2y=d(b^2-a^2),即
兩式相加有2n=d(b2+a2)2n=d(b^2+a^2),所以d2nd|2n
不妨設a<ba<b,由a2+b2=2nda^2+b^2=\frac{2n}{d}a2<nda^2<\frac{n}{d}
枚舉d,ad,a,然後求出bb,然後判gcd(a,b)==1gcd(a,b)==12n=d(b2+a2)2n=d(b^2+a^2)即可qwq

毒瘤代碼

#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#define re register int
#define rl register ll
using namespace std;
typedef long long ll;
int read() {
	re x=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9') {
		if(ch=='-')	f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9') {
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*f;
}
const int Size=10005;
const int INF=0x3f3f3f3f;
ll n,t,num[Size];
int main() {
	n=read();
	int tot=0;
	ll sn=sqrt(t=(n<<1));
	//先對2n分解質因數 
	for(re i=1; i<sn; i++) {
		if(t%i==0) {
			num[++tot]=i;
			num[++tot]=t/i;
		}
	}
	if(t%sn==0)	num[++tot]=sn;
	int ans=0;
	for(re i=1; i<=tot; i++) {
		ll d=num[i],maxa=n/d;
		for(rl a=1; a*a<maxa; a++) {
			ll b=sqrt(t/d-a*a);
			if(__gcd(a,b)==1 && d*(a*a+b*b)==t) {
				ans++;
			}
		}
	}
	printf("%d",(ans<<2)+4);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章