bzoj 1041: [HAOI2008]圆上的整点

Description

求一个给定的圆(x2+y2=r^2),在圆周上有多少个点的坐标是整数。

解题报告:
化简\(a^2+b^2=r^2\)
\(a^2=(r+b)(r-b)\)
提出(r+b)和(r-b)的公因子d
\(a^2=d^2*(r+b)/d*(r-b)/d\)
此时(r+b)/d和(r-b)/d 互质,所以两者都为完全平方数
所以令p,q分别为两者的平方根
可以得出\(p^2+q^2=2r/d\)
找出这样的搭配个数即是答案,所以枚举d和p,check(q)即可
这样求出的是第一象限的答案,最后再乘四加四即可

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
ll gcd(ll x,ll y){
	return x%y?gcd(y,x%y):y;
}
void work()
{
	ll n,t,tmp,ans=0,x,y,lim;
	cin>>n;n<<=1;lim=sqrt(n);
	for(int i=1;i<=lim;i++){
		if(n%i)continue;
		t=n/i;tmp=sqrt(t/2);
		for(int j=1;j<=tmp;j++){
			x=t-j*j;y=sqrt(x);
			if(!x)continue;
			if(y*y==x && x!=j*j && gcd(x,j*j)==1)
				ans++;
		}
		if(i==t)continue;
		tmp=sqrt(i/2);
		for(int j=1;j<=tmp;j++){
			x=i-j*j;y=sqrt(x);
			if(!x)continue;
			if(y*y==x && x!=j*j && gcd(x,j*j)==1)
				ans++;
		}
	}
	printf("%lld\n",(ans<<2)+4);
}

int main()
{
	work();
	return 0;
}

posted @ 2017-09-13 09:34  PIPIBoss  阅读(181)  评论(0编辑  收藏  举报