zoukankan      html  css  js  c++  java
  • BZOJ1041 [HAOI2008]圆上的整点

    Description

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

    Input

      只有一个正整数n,n<=2000 000 000

    Output

      整点个数

    Sample Input

    4

    Sample Output

    4

    题解

    显然可以O(r)枚举x...

    我们只考虑第一象限的点,最后乘四再加四(坐标轴上的点)。

    考虑这个式子:

    $$egin{aligned}
    x^2+y^2&=r^2\
    x^2&=r^2-y^2\
    x^2&=(r-y)(r+y)end{aligned}$$

    我们令$d = gcd(r+y, r-y), A = frac{r-y}d, B = frac{r+y}d$,则

    $$x^2 = d^2 AB$$

    又$gcd(A, B)=1$,所以$A, B$都是完全平方数。

    再令$A = a^2, B = b^2$,则

    $$a^2 = frac{r-y}d$$

    $$b^2 = frac{r+y}d$$

    两式相加得

    $$a^2+b^2 = frac{2r}d$$

    又$a<b$,所以

    $$a^2<frac{r}d$$

    那么我们只需枚举$d|2r$,再枚举$a<sqrt{frac{r}d}$,计算$B=frac{2r}d - a^2$是否是完全平方数且与$A$互质即可。

    具体,我们枚举$din[1, sqrt(2r)]$,判断是否有$d|2r$,如果是,那么对$d=d$和$d=frac{2r}d$枚举a。

    附代码(代码中$A,B$对应推导中的$a,b$):

    #include <cmath>
    #include <cstdio>
    typedef long long LL;
    LL gcd(LL a, LL b) {
      while (b) {
        LL t = b;
        b = a % b;
        a = t;
      }
      return a;
    }
    LL r;
    inline bool check(LL d, LL A) {
      LL B = (LL)sqrt(2 * r / d - A * A);
      return A * A + B * B == 2 * r / d && gcd(A, B) == 1;
    }
    int main() {
      scanf("%lld", &r);
      LL ans = 0;
      for (LL d = 1; d * d <= 2 * r; ++d)
        if (!(2 * r % d)) {
          for (LL A = 1; A * A < r / d; ++A)
            ans += check(d, A);
          if (d * d != 2 * r)
            for (LL A = 1; A * A < d / 2; ++A)
              ans += check(2 * r / d, A);
        }
      printf("%lld
    ", (ans + 1) * 4);
      return 0;
    }
    

      

  • 相关阅读:
    R语言学习笔记:向量化
    R语言笔记:快速入门
    再分析 返回值加引用&,const
    matlab 怎么保存plot的图 到指定文件夹
    不要在头文件中使用 using namespace std;
    散列表 (Hash table,也叫哈希表)
    重载操作符 operator overloading 学习笔记
    转 XMLHttpRequest().readyState的五种状态详解
    值得回味的基础知识理解加深
    完美解决fixed 水平居中问题
  • 原文地址:https://www.cnblogs.com/y-clever/p/6986420.html
Copyright © 2011-2022 走看看