给定一个正整数kkk,有kkk 次询问,每次给定三个正整数nin_ini, eie_iei, did_idi,求两个正整数 pi,qip_i,q_ipi,qi,使 ni=pi×qin_i = p_i × q_ini=pi×qi,ei×di=(pi−1)(qi−1)+1e_i × d_i = (p_i − 1)(q_i − 1) + 1ei×di=(pi−1)(qi−1)+1。
输入格式
第一行一个正整数kkk,表示有 kkk 次询问。
接下来kkk行,第 i 行三个正整数 ni,di,ein_i, d_i, e_ini,di,ei。
输出格式
输出 kkk 行,每行两个正整数 pi,qip_i, q_ipi,qi 表示答案。
为使输出统一,你应当保证 pi≤qip_i ≤ q_ipi≤qi。
如果无解,请输出 NO。
数据范围
以下记 m=n−e×d+2m = n − e × d + 2m=n−e×d+2。
保证对于 100%100\%100% 的数据,1≤k≤1051 ≤ k ≤ 10^51≤k≤105,对于任意的 1≤i≤k1 ≤ i ≤ k1≤i≤k,1≤ni≤10181 ≤ n_i ≤ 10^{18}1≤ni≤1018,1≤ei×di≤10181 ≤ e_i × d_i ≤ 10^{18}1≤ei×di≤1018,1≤m≤1091 ≤ m ≤ 10^91≤m≤109。
输入样例:
10
770 77 5
633 1 211
545 1 499
683 3 227
858 3 257
723 37 13
572 26 11
867 17 17
829 3 263
528 4 109
输出样例:
2 385
NO
NO
NO
11 78
3 241
2 286
NO
NO
6 88
C++代码
#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
int main() {
int tt;
cin >> tt;
while(tt --) {
LL n, c, d, p, q;
//n = p * q
//c * d = p * q - p - q + 2
//c * d = n - p - q + 2
//t = c * d
//p + q = n - t + 2
//p * q = n
cin >> n >> c >> d;
LL t = c * d;
LL s = n - t + 2;//p + q
LL x = s * s;//(p + q) ^ 2
LL y = x - 4 * n;//(p - q) ^ 2
LL z = LL(sqrt(y));//|p - q|
if(z * z != y) cout << "NO" << '\n';
else {
p = (s + z) / 2;
q = (s - z) / 2;
if(p > q) swap(p, q);
cout << p << " " << q << '\n';
}
}
return 0;
}
这篇博客介绍了一种算法来处理正整数问题,通过询问次数,找到满足ni=p*q且c*d=p*q-p-q+2的整数pi和qi。关键步骤包括计算t=c*d和p+q=n-t+2的解决方案,最后提供了C++代码实现。
593

被折叠的 条评论
为什么被折叠?



