当前位置: 首页> 健康> 养生 > 免费搭建网页游戏平台_律师关键词推广_网络推广怎么样_推广之家app下载

免费搭建网页游戏平台_律师关键词推广_网络推广怎么样_推广之家app下载

时间:2025/7/9 22:23:59来源:https://blog.csdn.net/Antonio915/article/details/142835458 浏览次数:0次
免费搭建网页游戏平台_律师关键词推广_网络推广怎么样_推广之家app下载

Indeterminate Equation

#质因子分解 #数学 #二分 #分治

题目描述

Given positive integers n, k, find the number of positive integer solutions to the indeterminate equation a k − b k = n a^k − b^k = n akbk=n

输入格式

The first line of input is an integer T ( 1 ≤ T ≤ 20 ) (1 ≤ T ≤ 20) (1T20) indicating the number of queries. The following T lines,
each contain two integers n, k indicating a single query. It is guaranteed that 1 ≤ n ≤ 1 0 18 1 ≤ n ≤ 10^{18} 1n1018, 3 ≤ k ≤ 64 3 ≤ k ≤ 64 3k64.

输出格式

For each query, output a single line contains a single integer, indicating the answer

样例 #1

样例输入 #1

3
7 3
15 4
31 5

样例输出 #1

1
1
1

解法

解题思路

首先对于 a k − b k a^k - b^k akbk,我能够提出一个 ( a − b ) (a-b) (ab),例如当 k = 3 k=3 k=3时,我们可以得到
a 3 − b 3 = ( a − b ) ( a 2 + a b + b 2 ) a^3-b^3 = (a-b)(a^2+ab+b^2) a3b3=(ab)(a2+ab+b2)

由于 n ≤ 1 e 18 n\leq 1e18 n1e18,所以我们可以通过大数质因子 p o l l a r d − r h o pollard-rho pollardrho分解出所有 n n n的质因子,然后跑 d f s dfs dfs搜索出所有的因子,因为在 1 e 18 1e18 1e18以内,因子个数不超过 1 e 5 1e5 1e5个。

那么我们就可以枚举 n n n的因子作为 a − b a-b ab的值,二分出满足条件的 b b b即可。

注意 a k − b k a^k -b^k akbk极有可能爆 _ _ i n t 128 \_\_int128 __int128,因此我们需要提前找出一个 a k − b k ≤ n a^k - b^k \leq n akbkn的上界。

由于当 k = 3 k=3 k=3时,上界可以到达接近 5 e 8 5e8 5e8,我们特判一下这个情况即可。

代码

using pii = std::pair<int, int>;const int N = 2e5 + 10;int mul(int a, int b, int m)
{int r = a * b - m * (int)(1.L / m * a * b);return r - m * (r >= m) + m * (r < 0);
}
int mypow(int a, int b, int m)
{int res = 1 % m;for (; b; b >>= 1, a = mul(a, a, m)){if (b & 1){res = mul(res, a, m);}}return res;
}
int B[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
int ctz(unsigned int n) {if (n == 0) return 32; // 处理边界情况int count = 0;while ((n & 1) == 0) {n >>= 1;count++;}return count;
}bool MR(int n)
{if (n <= 1)return 0;for (int p : B){if (n == p)return 1;if (n % p == 0)return 0;}int m = (n - 1) >> ctz(n - 1);for (int p : B){int t = m, a = mypow(p, m, n);while (t != n - 1 && a != 1 && a != n - 1){a = mul(a, a, n);t *= 2;}if (a != n - 1 && t % 2 == 0)return 0;}return 1;
}int PR(int n)
{for (int p : B){if (n % p == 0)return p;}auto f = [&](int x) -> int{ x = mul(x, x, n) + 1; return x >= n ? x - n : x; };int x = 0, y = 0, tot = 0, p = 1, q, g;for (int i = 0; (i & 255) || (g = std::gcd(p, n)) == 1; i++, x = f(x), y = f(f(y))){if (x == y){x = tot++;y = f(x);}q = mul(p, std::abs(x - y), n);if (q)p = q;}return g;
}std::vector<int> fac(int n) {
#define pb emplace_backif (n == 1)return {};if (MR(n))return { n };int d = PR(n);auto v1 = fac(d), v2 = fac(n / d);auto i1 = v1.begin(), i2 = v2.begin();std::vector<int> ans;while (i1 != v1.end() || i2 != v2.end()){if (i1 == v1.end()){ans.pb(*i2++);}else if (i2 == v2.end()){ans.pb(*i1++);}else{if (*i1 < *i2){ans.pb(*i1++);}else{ans.pb(*i2++);}}}return ans;
}__int128_t quick(__int128_t x, int n)
{__int128_t res = 1;while (n){if (n & 1)res = (res * x);x = x * x;n >>= 1;}return res;
}std::ostream& operator<<(std::ostream& os, __int128_t n) {std::string s;while (n) {s = s + std::to_string((int)n % 10);n /= 10;}std::reverse(s.begin(), s.end());return os << s;
}std::vector<int> getfac(int n) {std::vector<int> pos = fac(n);std::map<int, int> cnt;for (auto i : pos) cnt[i]++;std::vector<pii> tmp;for (auto& [x, y] : cnt) tmp.push_back({ x, y });int len = tmp.size();std::set<int> st;auto dfs = [&](auto&& self, int mul, int dep) ->void {if (n % mul == 0)st.insert(mul);if (dep == len)return;int p = 1;for (int i = 0; i <= tmp[dep].second; i++) {if (i != 0)p *= tmp[dep].first;self(self, mul * p, dep + 1);}};dfs(dfs, 1, 0);std::vector<int>res;for (auto& x : st) res.emplace_back(x);return  res;
}void solve()
{int n, k;std::cin >> n >> k;int limit = 0,res = 0;if (k == 3) {limit = 5e8;}for (int i = 1; i <= 1e6; i++) {if (quick(i, k) - quick(i - 1, k) > n) {limit = i;break;}}auto factor = getfac(n);for (auto x : factor) {int l = 1, r = limit ,ans = 0;while (l <= r) {int mid = l + r >> 1;__int128_t a = mid + x, b = mid;int ok = 0;a = quick(a, k), b = quick(b, k);if (a - b == n) {ans = mid;break;}else if (a - b > n) r = mid - 1;else l = mid + 1;}res += ans;}std::cout << res << "\n";}signed main() {std::ios::sync_with_stdio(0);std::cin.tie(0);std::cout.tie(0);int t = 1;std::cin >> t;while (t--) {solve();}
};
关键字:免费搭建网页游戏平台_律师关键词推广_网络推广怎么样_推广之家app下载

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: