HDUOJ 4282 A very hard mathematic problem

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cctype>
#define CLOSE() ios::sync_with_stdio(false)
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
const int maxn = 46500;
using LL = long long;
using UI = unsigned int;
using namespace std;
//------------------------------------------------------------------------------------------//

//暴力枚举,注意z = 2时为完全平方,单独处理,避免tle
using ULL = unsigned long long;
ULL a[maxn][31];
ULL qpow(ULL a, ULL b) {
	ULL ret = 1;
	while (b) {
		if (b & 1) ret = ret * a;
		a = a * a;
		b >>= 1;
	}
	return ret;
}

int main() {
#ifdef _DEBUG
	IN(); OUT();
#endif
	ULL k;
	ULL x, y, z;
	while (scanf("%lld", &k) && k) {
		int cnt = 0;
		ULL t = (ULL)sqrt(k);
		if (t * t == k) cnt += (t - 1) / 2;
		for (z = 3; z <= 30; ++z) {
			for (x = 1; ; ++x) {
				ULL xz = qpow(x, z);
				if (xz * 2 >= k) break;
				for (y = x + 1; ; y++) {
					ULL yz = qpow(y, z);
					if (xz + yz + x* y* z > k) break;
					if (xz + yz + x * y * z == k) {
						cnt++;
						printf("%lld = %lld^%lld + %lld^%lld + %lld * %lld * %lld\n", k, x, z, y, z, x, y, z);
					}
				}
			}
		}
		cout << cnt << endl;
	}
	return 0;
}

#include <cstdio>
#include <cmath>
#define OUT() freopen("out.txt", "w", stdout);
#define IN() freopen("in.txt", "r", stdin);

using namespace std;

const int maxn = 46500;
using ULL = unsigned long long;



//二分法,枚举y, z二分x。
ULL a[maxn][31];
ULL qpow(ULL a, ULL b) {
	ULL ret = 1;
	while (b) {
		if (b & 1) ret = ret * a;
		a = a * a;
		b >>= 1;
	}
	return ret;
}

void fun() {
	for (ULL i = 1; i < maxn; ++i) {
		for (ULL j = 2; j <= 30; ++j) {
			ULL t = qpow(i, j);
			if (t < 2147483648) {
				a[i][j] = t;
				//cout << t << endl;
			}
		}
	}
}

int main() {
#ifdef _DEBUG
	IN(); OUT();
#endif
	fun();
	ULL k;
	ULL x, y, z;
	while (scanf("%lld", &k) && k) {
		int cnt = 0;
		for (z = 2; z <= 30; ++z) {
			int t = sqrt(k) + 1;
			for (y = 2; y <= t; ++y) {
				if (!a[y][z]) break;
				if (a[y][z] + y*z >= k) break;
				ULL l = 1, r = y-1;
				while (l <= r) {
					x = (l + r) / 2;
					ULL t = a[x][z] + a[y][z] + x*y*z;
					if (t > k) r = x - 1;
					else if (t < k) l = x + 1;
					else {
						cnt++;
						//printf("%lld = %lld^%lld + %lld^%lld + %lld * %lld * %lld\n", k, x, z, y, z, x, y, z);
						break;
					}
				}
			}
		}
		printf("%d\n", cnt);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值