zoukankan      html  css  js  c++  java
  • hdu 4282 枚举,非二分

    http://acm.hdu.edu.cn/showproblem.php?pid=4282

    对于方程X^Z + Y^Z + XYZ = K,已知K求此方程解的个数,其中要求X<Y,Z>1,而K的范围是0到2^31。

    首先我们来分析Z的范围:由于X,Y为正整数,X < Y,则1 < X < Y, =====> Y >= 2
    => X^Z + Y^Z + XYZ > Y^Z
    => 2^Z <= Y^Z < 2^31
    所以得到2 <= Z<31
    对于Z=2时式子左边可以化为(x+y)^2 = k 的形式。
    所以当k 是完全平方数的时候,(x,y) 才有可能有解。
    假如m^2 = k ,问题就相当于求x+y = m (x < y) 的解的组数。
    容易得出ans=(m-1)/2。

    而Z在3<=Z<31的情况。
    我们再来分析X的范围:
    对于方程X^Z + Y^Z + XYZ = K, X < Y,则有X^Z + Y^Z + XYZ > 2*X^Z + X*X*Z >= 2*X^3 + 3*X^2
    即我们得到:2*X^3 + 3*X^2 < 2^31 解这个方程有:X < 1024
    于是现在我们得到了3 <= Z < 31,1 <= X < 1024,当然Z=2特殊处理。接下来就直接枚举X,Z,再枚举Y。

    复杂度O(10^4)左右,因为y不会和相差太远

    #pragma comment(linker, "/STACK:36777216")
    #pragma GCC optimize ("O2")
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%I64d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    #define eps 1e-9
    const double pi = acos(-1.0);
    typedef long long LL;
    typedef unsigned long long ULL;
    const int modo = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int maxn = 1005,N = 50000;
    LL s,k,ans;
    LL f[1300][32];
    void init()
    {
        for(int i = 1; i < 1300;++i){
            f[i][0] = 1;
            for(int j = 1;j < 32;++j){
                f[i][j] = f[i][j-1]*i;
                if(f[i][j] > (1LL<<31))
                    break;
            }
        }
    }
    int main(){
        init();
        while(~RD(k),k){
            ans = 0;
            s = sqrt(k);
            if(s * s == k){
                ans += (s - 1)/ 2;
            }
            for(int x = 1;x < 1024;++x){
                for(int z = 3;z < 31;++z){
                    if(f[x][z] == 0)
                        break;
                    for(int y = x + 1;;++y){
                        if(f[y][z] == 0 || f[x][z] + f[y][z] + x*y*z > k)
                            break;
                        else if(f[x][z] + f[y][z] + x*y*z == k){
                            ans ++ ;
                            break;
                        }
                    }
                }
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)
    Java内部类详解 2
    内部类详解(很详细)
    《JAVA与模式》之简单工厂模式
    《JAVA与模式》之适配器模式
    多态
    java Final关键字
    java实例初始化块
    tween.js
    three.js 之旅 (三)
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4074381.html
Copyright © 2011-2022 走看看