x * x + y * y = r * r
的(正整数解 + 1) << 2
两种方法:
wiki一下勾股数有一个不假证明的参数方程组,消元变成了2元
另一种方法:
(r - x)(r + x) = y * y
d = gcd (r - x, r + x) y * y = d * (u * u * v * v)
2 * r = d * (u * u + v * v)
利用最后一个狮子:枚举2r的约数,枚举约数的uv分解(有方向).
我是抄的 你也去抄一份吧
1 #include <cstdio> 2 #include <cmath> 3 long long r; 4 inline long long gcd (long long a, long long b) { return b == 0 ? a : gcd (b, a % b); } 5 inline long long sol (long long d) 6 { 7 long long z (0), n (2 * r / d); 8 for (long long u = 1; u * u <= n; u ++) 9 { 10 long long t = n - u * u; 11 long long v = (long long)sqrt (t + 0.5); 12 if (u >= v) break; 13 if (u * u + v * v == n && gcd (u, v) == 1) 14 z ++; 15 } 16 return z; 17 } 18 int main () 19 { 20 scanf ("%d", &r);long long ans (1), n (2 * r); 21 for (long long i = 1; i * i <= n; i ++) 22 if (n % i == 0) 23 { 24 ans += sol (i); 25 if (i * i == n) break; 26 ans += sol (n / i); 27 }printf ("%lld\n", ans << 2); 28 return 0; 29 }