• YbtOJ20001 立方数差


    小w又来氵题解啦~~

    链接

    戳这里

    题目

    题目描述

    给出一个质数 ,要求你判断这个质数是否是两个立方数的差,即判断是否存在正整数(a,b)满足(a^3-b^3=p)

    输入格式

    从文件cubicp.in中读入数据。

    多组数据。

    第一行给出一个(T) ,表示有(T)组数据。

    接下来(T)行,每行一个质数(p)

    输出格式

    输出到文件cubicp.out中。

    输出(T)行,对于每个数如果是立方差数,输出YES,否则输出NO

    样例?不想放了

    数据范围

    对于(30\%)的数据,(2≤p≤100);

    对于(60\%)的数据,(2≤p≤10^6)

    对于(100\%)的数据(2≤p≤10^{12}),(1≤T≤100),并且保证每个(p)均为质数。

    思路

    看了这道题……很明显,这是一道数学题(你这不是废话吗)。

    首先,这里有一个立方差。

    由立方差公式:(a^3-b^3=(a-b)(a^2+ab+b^3))

    可得:(p=a^3-b^3=(a-b)(a^2+ab+b^3)) (字母都一样啊喂!)

    (p) 为质数

    ((a-b)=1)

    这里小w解释一下:因为题目中已经说(p)是质数了,所以((a-b))((a^2+ab+b^2))肯定有一个为(1)(要是有其他的就不是质数了对吧)

    而要是((a^2+ab+b^2)=1)的话,我们就会明显地发现:(a^3-b^3=a-b)

    明显不成立

    所以这里只能让((a-b)=1)

    接着继续:

    (b=a-1)

    这个也不用多说了吧?简易方程五年级下学期谢谢。

    然后我们就只需要枚举一个(a)(frac{p}{2})。因为(p)最大为(10^{12}),所以这里也就是(10^6)

    这样的话,单次时间复杂度为(O(frac{p}{2})),总共为(O(frac{pt}{2}))

    贴下代码:

    Code1:

    #include <cstdio>
    using namespace std;
    
    long long p;
    long long t;
    bool flag;
    
    inline long long read() {
        long long x = 0, f = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-')
                f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = (x << 1) + (x << 3) + (ch ^ 48);
            ch = getchar();
        }
        return x * f;
    }
    
    int main() {
        freopen("cubicp.in", "r", stdin);
        freopen("cubicp.out", "w", stdout);
        t = read();
        for (int i = 1; i <= t; i++) {
            flag = false;
            p = read();
            for (long long i = 1; i <= 1000000; i++) {
                if (p == (i - 1) * (i - 1) + i * i + i * (i - 1)) {
                    printf("YES
    ");
                    flag = true;
                    break;
                }
            }
            if (flag == true)
                continue;
            printf("NO
    ");
        }
        return 0;
    }
    
    

    但是!这还远远没有完。虽然刚刚我们的时间复杂度已经可以通过这道题了,但我们可以把单次时间压缩为(O(1))

    这个想法来自于lmt(%%%),他写出了比标程还快的程序!

    刚刚我们已经推到了(p=(a^2+ab+b^2)),并且(b=a-1)

    那么(p=(a^2-2ab+b^2+3ab))

    由完全平方公式(a^2-2ab+b^2=(a-b)^2)

    可得:(p=(a-b)^2+3ab)

    ((a-b)=1)

    (p=1+3ab)

    (b=a-1)

    (p=1+3a(a-1))

    这样的话,如果((p-1)%3≠0),也就是说(p-1)并不是(3)的倍数,这就意味着这个肯定不成立,可以直接输出NO

    若成立,那么(p=3a(a-1))

    那么(lfloor sqrt{p} floor=a-1)

    那么有人就一脸懵逼了:

    ?????

    这是什么鬼操作???

    首先,我们已知(p=a(a-1))

    那么((a-1)<sqrt{p}<a)

    此时(lfloor sqrt{p} floor=a-1)

    还可以得出(lfloor sqrt{p} floor +1=a)

    这样,我们就无须枚举(a),成功把时间降到线性。单次时间复杂度(O(1)),总共为(O(t))

    Code2

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int n;
    long long p;
    int main() {
        freopen("cubicp.in", "r", stdin);
        freopen("cubicp.out", "w", stdout);
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> p;
            p -= 1;
            if (p % 3 != 0) {
                cout << "NO" << endl;
                continue;
            } else {
                p /= 3;
                long long f = sqrt(p);
                if (f * (f + 1) == p) {
                    cout << "YES" << endl;
                } else {
                    cout << "NO" << endl;
                }
            }
        }
        return 0;
    }
    

    至此,这篇题解就氵完了

  • 相关阅读:
    Linux服务器因为Nginx日志access.log文件过大项目无法访问的问题
    【译】StackExchange.Redis 中文文档(二)配置
    【译】StackExchange.Redis 中文文档(一)基础
    Redis应用(一)实时在线用户
    [.NET]Thread与Task的区别
    并查集(UnionFind)技巧总结
    [LeetCode题解]377. 组合总和 Ⅳ
    [LeetCode题解]216. 组合总和 III
    [LeetCode题解]39. 组合总和
    [LeetCode题解]40. 组合总和 II
  • 原文地址:https://www.cnblogs.com/w-rb/p/13885737.html
Copyright © 2020-2023  润新知