BZOJ1041 圓上的整點 Solution

題意:給定r,求x^2+y^2=r^2的圖象上存在多少個整點。


Sol:問題顯然可以轉化爲x^2+y^2=r^2有多少個正整數解。我們考慮如何快速的解出這個方程。

引入本源勾股數組(x,y,z)(x,y,z爲正整數),滿足x^2+y^2=z^2且gcd(x,y,z)=1.

我們能夠證明一些性質,z爲奇數,x,y一奇一偶,不妨設x爲奇數,y爲偶數,則有z-x爲完全平方數的二倍,z-y爲完全平方數。

有興趣的可以自己證一下,當做結論記住也行。

那麼我們枚舉最大公約數,然後計算對應的本源勾股數組數目。

具體怎麼計算看代碼,枚舉量很小。

最終算出的答案只是1/8個象限,於是*8+4得到最終答案。

Code:

#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
 
typedef long long LL;
 
inline int gcd(int x, int y) {
    return (!y) ? x : gcd(y, x % y);
}
inline int isint(long long x) {
    int tmp = (int)sqrt(x);
    if ((LL)tmp * tmp != x)
        return -1;
    return tmp;
}
 
inline int Calc(int z) {
    if ((z & 1) == 0)
        return 0;
    if (z < 5)
        return 0;
    int res = 0;
    int x, y;
    for(int i = 1; i * i < z; i += 2) {
        x = z - i * i;
        y = isint((LL)z * z - (LL)x * x);
        if (y == -1 || gcd(z, gcd(x, y)) != 1)
            continue;
        ++res;
    }
    return res;
}
 
int main() {
    int x;
    scanf("%d", &x);
     
    if (!x) {
        puts("1");
        return 0;
    }
     
    long long res = 0;
    for(int i = 1; i * i <= x; ++i) {
        if (x % i == 0) {
            res += Calc(x / i);
            if (i != x / i)
                res += Calc(i);
        }
    }
     
    printf("%lld", (res << 3) + 4);
     
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章