题目传送门
[CSP-J 2022] 解密(民间数据)
题目描述
给定一个正整数 k k k,有 k k k 次询问,每次给定三个正整数 n i , e i , d i n_i, e_i, d_i ni,ei,di,求两个正整数 p i , q i p_i, q_i pi,qi,使 n i = p i × q i n_i = p_i \times q_i ni=pi×qi、 e i × d i = ( p i − 1 ) ( q i − 1 ) + 1 e_i \times d_i = (p_i - 1)(q_i - 1) + 1 ei×di=(pi−1)(qi−1)+1。
输入格式
第一行一个正整数 k k k,表示有 k k k 次询问。
接下来 k k k 行,第 i i i 行三个正整数 n i , d i , e i n_i, d_i, e_i ni,di,ei。输出格式
输入 k k k 行,每行两个正整数 p i , q i p_i, q_i pi,qi 表示答案。
为使输出统一,你应当保证 p i ≤ q i p_i \leq q_i pi≤qi。
如果无解,请输出NO
。样例 #1
样例输入 #1
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
样例输出 #1
2 385 NO NO NO 11 78 3 241 2 286 NO NO 6 88
提示
【样例 #2】
见附件中的decode/decode2.in
与decode/decode2.ans
。
【样例 #3】
见附件中的decode/decode3.in
与decode/decode3.ans
。
【样例 #4】
见附件中的decode/decode4.in
与decode/decode4.ans
。
【数据范围】
以下记 m = n − e × d + 2 m = n - e \times d + 2 m=n−e×d+2。
保证对于 100 % 100\% 100% 的数据, 1 ≤ k ≤ 10 5 1 \leq k \leq {10}^5 1≤k≤105,对于任意的 1 ≤ i ≤ k 1 \leq i \leq k 1≤i≤k, 1 ≤ n i ≤ 10 18 1 \leq n_i \leq {10}^{18} 1≤ni≤1018, 1 ≤ e i × d i ≤ 10 18 1 \leq e_i \times d_i \leq {10}^{18} 1≤ei×di≤1018
, 1 ≤ m ≤ 10 9 1 \leq m \leq {10}^9 1≤m≤109。
测试点编号 k ≤ k \leq k≤ n ≤ n \leq n≤ m ≤ m \leq m≤ 特殊性质 1 1 1 1 0 3 10^3 103 1 0 3 10^3 103 1 0 3 10^3 103 保证有解 2 2 2 1 0 3 10^3 103 1 0 3 10^3 103 1 0 3 10^3 103 无 3 3 3 1 0 3 10^3 103 1 0 9 10^9 109 6 × 1 0 4 6\times 10^4 6×104 保证有解 4 4 4 1 0 3 10^3 103 1 0 9 10^9 109 6 × 1 0 4 6\times 10^4 6×104 无 5 5 5 1 0 3 10^3 103 1 0 9 10^9 109 1 0 9 10^9 109 保证有解 6 6 6 1 0 3 10^3 103 1 0 9 10^9 109 1 0 9 10^9 109 无 7 7 7 1 0 5 10^5 105 1 0 18 10^{18} 1018 1 0 9 10^9 109 保证若有解则 p = q p=q p=q 8 8 8 1 0 5 10^5 105 1 0 18 10^{18} 1018 1 0 9 10^9 109 保证有解 9 9 9 1 0 5 10^5 105 1 0 18 10^{18} 1018 1 0 9 10^9 109 无 10 10 10 1 0 5 10^5 105 1 0 18 10^{18} 1018 1 0 9 10^9 109 无 附件
decode.zip 1.74kb
二分方法
俗话说得好,看题先看数据范围。
一开始我没看范围,一看是一道橙题立马打了暴力,然后就…
由于这道题数据范围很大,只能考虑O(logn)和O(1)的复杂度
要解出这道题,我们先要了解韦达定理:
然后看题目中的两句话:
求两个正整数 p i , q i p_i, q_i pi,qi,使 n i = p i × q i n_i = p_i \times q_i ni=pi×qi、 e i × d i = ( p i − 1 ) ( q i − 1 ) + 1 e_i \times d_i = (p_i - 1)(q_i - 1) + 1 ei×di=(pi−1)(qi−1)+1。
以下记 m = n − e × d + 2 m = n - e \times d + 2 m=n−e×d+2。
推导亿下:
m = n − e × d + 2 m = n - e \times d + 2 m=n−e×d+2
m = p i × q i − ( p i − 1 ) ( q i − 1 ) + 1 + 2 m = p_i \times q_i-(p_i - 1)(q_i - 1)+1+2 m=pi×qi−(pi−1)(qi−1)+1+2
m = p i × q i − ( p i × q i − p i − q i + 1 + 1 ) + 2 m = p_i \times q_i-(p_i \times q_i - p_i - q_i+1+1)+2 m=pi×qi−(pi×qi−pi−qi+1+1)+2
m = p i × q i − p i × q i + p i + q i − 1 − 1 + 2 m = p_i \times q_i-p_i \times q_i + p_i + q_i-1-1+2 m=pi×qi−pi×qi+pi+qi−1−1+2
m = p i + q i m = p_i+q_i m=pi+qi
这样我们就得到了两个式子:
n = p × q n = p \times q n=p×q
m = p + q m = p + q m=p+q
这就是韦达定理!!!
然后又发现一件事情,如果
p
p
p的值确定了,那么
q
q
q的值也就可以通过
n
n
n来求解,所以说可以用二分的方式,在
1
1
1~
n
n
n的范围里二分,从而求出答案。
但是这题还有一个更简单的方法:
O(1)做法
在刚刚的结论上再推导亿下:
e i × d i = ( p i − 1 ) ( q i − 1 ) + 1 e_i \times d_i=(p_i-1)(q_i-1)+1 ei×di=(pi−1)(qi−1)+1
e i × d i = p i × q i − p i − q i + 1 + 1 e_i \times d_i= p_i \times q_i-p_i-q_i+1+1 ei×di=pi×qi−pi−qi+1+1
将 n = p i × q i n=p_i \times q_i n=pi×qi带入原式得:
e i × d i = n − p i − q i + 2 e_i\times d_i=n-p_i-q_i+2 ei×di=n−pi−qi+2
把原式颠倒一下:
p i + q i = n − e i × d i + 2 p_i + q_i = n-e_i\times d_i+ 2 pi+qi=n−ei×di+2
所以我们就得到了以下结论:
p i + q i = n − e i × d i + 2 p_i + q_i = n-e_i\times d_i+ 2 pi+qi=n−ei×di+2
p i × q i = n p_i\times q_i = n pi×qi=n
那么发现一个问题:
n
,
e
,
d
n,e,d
n,e,d都是已知的。
那就说明,
p
i
+
q
i
p_i + q_i
pi+qi和
p
i
×
q
i
p_i\times q_i
pi×qi都是已知的。
那如何求
p
i
,
q
i
p_i,q_i
pi,qi呢?
假设两数之和是 s 1 s1 s1,两数之积是 s 2 s2 s2
a + b = s 1 a+b=s1 a+b=s1
a × b = s 2 a\times b=s2 a×b=s2
a = s 1 − b a=s1-b a=s1−b
( s 1 − b ) × b = s 2 (s1-b)\times b=s2 (s1−b)×b=s2
s 1 × b − b × b = s 2 s1\times b-b\times b=s2 s1×b−b×b=s2
这样,就成功地用O(n)的复杂度切掉了一道橙题,滑稽~