HDU 4282 (比较厉害的 二分)

来源:互联网 发布:淘宝怎么联系客服 编辑:程序博客网 时间:2024/05/02 01:47

题意:

有一个式子: X^Z + Y^Z + XYZ = K,现在给出K,问有多少XYZ的组成方式,
注意条件:X < Y, Z > 1,0 < K < 2^31;
思路:
若想直接暴力解决,需要三重循环,铁超。。。所以现在能不能加速?二分可以,
需要提前准备,如果提前把X^Z和Y^Z的所有情况算出来,那么事半功倍,枚举
X^Z然后查找Y既可。天才般的想法。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long LL;const int MAXN = 50005;int ans;LL k;LL a[MAXN][32];int check(LL temp,int x,int z){    int L = x+1,R = 50000,mid;    while(L <= R) {        mid = (L+R)>>1;        if(a[mid][z] == 0) {            R = mid - 1;            continue;        }        else if(a[mid][z] + x*mid*z < temp)            L = mid + 1;        else if(a[mid][z] + x*mid*z > temp)            R = mid - 1;        else            return true;    }    return false;}int main(){    //freopen("in.txt","r",stdin);    for(int i = 1;i <= 50000; i++) {        a[i][1] = i;        for(int j = 2;j <= 31; j++) {            a[i][j] = a[i][j-1]*i;            if(a[i][j] > 2147483648LL)                break;        }    }    while(scanf("%lld",&k) != EOF) {        ans = 0;        if(k == 0)            break;        for(int i = 1;i <= 50005 && i <= k; i++) {            for(int j = 2;j <= 31; j++) {                if(a[i][j] == 0)                    break;                LL temp = k - a[i][j];                if(k - i*j <= 0)                    continue;                if(check(temp,i,j))                    ans++;            }        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击