bzoj1041: [HAOI2008]圆上的整点(数论)

来源:互联网 发布:产品主数据 编辑:程序博客网 时间:2024/05/19 00:53

题目传送门
好神。

解法:
题面短的让我害怕。
想了半天没头绪。
把式子换了一波:y^2=r^2-x^2
y^2=(r+x)(r-x)
d=gcd(r-x,r+x)
A=(r+x)/d
B=(r-x)/d
那么y^2=d^2*A*B
所以A和B都是完全平方数
A+B=2*r/d
令a^2=A,b^2=B
那么a^2+b^2=2*r/d
所以枚举d。
然后枚举a。
根据d和a求出b看看b是否为整数。
而且a和b要互质。
因为一开始A和B都是除过最大公因数的所以A和B是互质的那么a和b也是互质的。

代码实现:

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#include<queue>using namespace std;typedef long long ll;ll n;ll gcd(ll x,ll y) {if(x>y)swap(x,y);if(x==0)return y;return gcd(y%x,x);}int main() {    scanf("%lld",&n);n*=2;ll t=ll(sqrt(double(n+1)));int ans=0;    for(ll i=1;i<=t;i++)if(n%i==0) {        ll tt=ll(sqrt(double(n/i+1)));        for(ll a=1;a<=tt;a++) {             ll B=n/i-a*a,b=ll(sqrt(double(B+1)));            if(a<b&&b*b==B&&gcd(a,b)==1)ans++;        }        if(i*i!=n) {            ll tt=ll(sqrt(double(i+1)));            for(ll a=1;a<=tt;a++) {                 ll B=i-a*a,b=ll(sqrt(double(B+1)));                if(a<b&&b*b==B&&gcd(a,b)==1)ans++;            }        }    }printf("%d\n",ans*4+4);    return 0;}
原创粉丝点击