// Problem: E2. Rudolf and Snowflakes (hard version)
// Contest: Codeforces - Codeforces Round 883 (Div. 3)
// URL: https://codeforces.com/problemset/problem/1846/E2
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1000000000000000000;
vector<ll> nums;
ll qpow(ll a, ll b)
{
ll ans = 1;
while (b)
{
if (b & 1)
{
ans *= a;
if (ans > maxn)
return INT64_MIN;
}
if (a > 1000000000)
return INT64_MIN;
a *= a;
b >>= 1;
}
return ans;
}
void solve()
{
for (ll i = 2; i <= 1000000; i++)
{
ll num1 = i - 1;
// cout << "-----------"
// << "\n";
// cout << "the i: " << i << " the num1: " << num1 << "\n";
long double t = log(maxn);
long double t2 = log(i);
for (ll j = 2; j < (ll)(t / t2); j++)
{
// cout << "the j: " << j << "\n";
ll s = qpow(i, j + 1);
if (s == INT64_MIN)
continue;
// cout << "the sum: " << s - 1 << "\n";
if ((s - 1) % num1 == 0)
{
// cout << "ok"
// << "\n";
// cout << (j == 2 ? i : 114514) << "\n";
nums.push_back((s - 1) / num1);
}
}
}
sort(nums.begin(), nums.end());
nums.erase(unique(nums.begin(), nums.end()), nums.end());
}
bool bs(ll n)
{
ll l = 0, r = nums.size() - 1, mid;
while (l < r)
{
mid = l + r >> 1;
if (nums[mid] == n)
return true;
else if (n > nums[mid])
l = mid + 1;
else
r = mid;
}
return false;
}
int main()
{
int t;
cin >> t;
solve();
while (t--)
{
ll n;
cin >> n;
if (n < 3)
{
cout << "NO"
<< "\n";
continue;
}
if (n >= 1000000000000ll)
{
// if (check(ll(n * 4) - 3))
// {
ll delta = 1 - 4 * (1 - n);
ll x = 0.5 * (-1 + sqrt(delta));
if (x * x + x + 1 == n)
cout << "YES"
<< "\n";
else
cout << "NO"
<< "\n";
// }
// else
// {
// cout << "NO"
// << "\n";
// }
}
else
{
if (bs(n))
cout << "YES"
<< "\n";
else
cout << "NO"
<< "\n";
}
}
return 0;
}
思路,利用等比数列求和公式。在 1012≤n 之前用上面的公式加二分。
在之后用方程 k2+k+1=n验证