【问题标题】:How to solve "X^2 - Y is perfect square, X, Y ≤ N" in O(sqrt(N)) time complexity? [closed]如何在 O(sqrt(N)) 时间复杂度中解决“X^2 - Y 是完美平方,X, Y ≤ N”? [关闭]
【发布时间】:2021-08-23 19:07:17
【问题描述】:

给定 N。求所有整数对 x,y 的个数,使得

1<=x, y<=N
and x^2 - y is a perfect square

N 很大,但 O(sqrt(N)) 可以解决这个问题。

我试图解决这个问题,比如让 z^2 成为平方数

x^2 - z^2 = y = (x+z)(x-z)
then let x + z = p and x - z = q;
then x = (p+q)/2 and z = (p-q)/2;
and (p+q)/2<=N;
and p and q should have same parity (both even or odd as (p+q)/2 is integer)
also pq<=N

现在我不知道如何从这里开始 或者告诉我一些其他有效解决这个问题的方法。

【问题讨论】:

  • 也许你可以迭代所有的(x,z),并返回对应的(x,y) = (x, (x+z)*(x-z))? x 从 1 循环到 N,z 从 0 循环到 sqrt(x**2 - 1)
  • 既然有 O(n^2) 个这样的对,你如何期望在不到 O(n^2) 的时间内枚举它们?还是您只想知道有多少这样的对?
  • @ChrisDodd 请注意 O() 表示上限;肯定有少于 n**2 对 (x,y) 使得 x**2-y 是一个完美的正方形,并且 1
  • 如果去掉 y 上的(上)边界,就会有 (n*n + n)/2 个这样的对(即 O(n^2))。使用 y 的上限,有更少但仍然至少 O(n*sqrt(n))。
  • 我投票结束这个问题,因为这是一个数论问题,而不是编程问题。添加 C++ 标签不会改变这一点。

标签: c++ c++17 dynamic-programming mathematical-optimization counting


【解决方案1】:

这个解决方案解决了 O(sqrt N) 中的问题。

重新表述问题

令 z^2 = x^2 - y, z ≥ 0,或等价于 0

我们需要N^2下的完全平方对,它们的差小于或等于N。通过算术级数,

1 + 3 + 5 + 7 + ... + (2k - 1) = k^2

这意味着 x^2 - z^2 是一些 n 个连续奇数的和。

计算奇数

z^2 + (2z + 1) + (2z + 3) + ... + (2x - 1) = x^2。应用算术级数公式

z^2 + n/2 * (4z + 2 + 2(n - 1)) = x^2

z^2 + n * (2z + n) = x^2

n(2z + n) ≤ N

z ≤ floor((N/n - n)/2)

因此,我们能够找到 z 的最后一个值,其中至少需要 n+1 个奇数连续整数才能使它们的总和超过 N。

对于每个 z,x 可以是 z+1, z+2 ... z+n,总共 n 对。

#include <cmath>
#include <iostream>
int N = 99; 
int main(void){
    int z = -1;
    // z = 0 is valid for x^2 < N, so -1 is largest invalid z.
    int count = 0;
    for (int n = std::sqrt(N); n > 0; n--){
        int zNew = (N/n - n)/2;
        // zNew is max z that has n perfect squares from z + 1 to z + n
        count += (zNew - z) * n;
        z = zNew;
    }
    std::cout << count << '\n';
}

Java 版本通过了这些单元测试。

(N, count) = (1, 1), (3, 2), (5, 4), (8, 6), (60, 68), (99, 124), (500, 808)

【讨论】:

  • 我进行了一些编辑以编译您的代码:将函数体放在大括号内,将参数 int n 添加到 getMaxX,将 findnStart 更改为返回结构,并将 main 更改为打印它的结果而不是返回它。程序打印 0,表示 N=99。我不知道错误是在代码中还是在算法中(或两者兼而有之)。抱歉,我现在没时间,今天大部分时间都没有。
  • @EricPostpischil 感谢您的意见!我会用另一种语言写它,看看它是否有效。出于某种原因,我看不到您的编辑,所以我只是假设我没有足够的积分或其他东西
  • 我没有将我的更改编辑到您的答案中;我只是在我的系统上尝试了它们。在确定更正之前,我不会编辑答案。
  • @EricPostpischil 我删除了“优化”,发现一个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 2019-12-09
  • 2019-12-13
  • 2022-01-20
相关资源
最近更新 更多