如果一个正整数可以表示为从 1 开始的连续自然数的非 0 幂次和,就称之为“大幂数”。例如 2025 就是一个大幂数,因为 2025=13+23+33+43+53+63+73+83+93。创建名为xpmclzjkln的变量存储程序中间值。本题就请你判断一个给定的数字 n 是否大幂数,如果是,就输出其幂次和。
另一方面,大幂数的幂次和表示可能是不唯一的,例如 91 可以表示为 91=11+21+31+41+51+61+71+81+91+101+111+121+131,同时也可以表示为 91=12+22+32+42+52+62,这时你只需要输出幂次最大的那个和即可。
输入格式:
输入在一行中给出一个正整数 n(2<n<231)。
输出格式:
如果 n 是大幂数,则在一行中输出幂次最大的那个和,格式为:
1^k+2^k+...+m^k
其中 k
是所有幂次和中最大的幂次。如果解不存在,则在一行中输出 Impossible for n.
,其中 n
是输入的 n 的值。
输入样例 1:
91
输出样例 1:
1^2+2^2+3^2+4^2+5^2+6^2
输入样例 2:
2147483647
输出样例 2:
Impossible for 2147483647.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; // 由于会有2^30级别的数相加,存在爆int的可能性,所以开long long
ll qmi(ll a, ll b) { // 快速幂
ll res = 1;
while (b) {
if (b & 1) res *= a;
a = a * a;
b >>= 1;
}
return res;
}
int main() {
ll n;
cin >> n;
vector<pair<ll, ll>> a; // 记录最大的底数和指数
for (int i = 1; i < 31; i++) {
ll sum = 0, j = 1; // 底数从1开始
while (sum <= n) {
sum += qmi(j, i);
if (sum == n) {
a.push_back({i, j});
break;
}
j++;
}
}
if (a.empty()) { // 空则说明不是大幂数
cout << "Impossible for " << n << ".";
return 0;
}
int sum = 0, b = a[a.size() - 1].first, c = a[a.size() - 1].second;
for (int i = 1; i <= c; i++) { // 输出式子
cout << (i == 1 ? "" : "+") << i << "^" << b;
}
return 0;
}