T1 [CSP-J 2022] 乘方(民间数据)
题目描述
小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数 aaa 和 bbb,求 aba^bab 的值是多少。
aba^bab 即 bbb 个 aaa 相乘的值,例如 232^323 即为 333 个 222 相乘,结果为 2×2×2=82 \times 2 \times 2 = 82×2×2=8。
“简单!”小文心想,同时很快就写出了一份程序,可是测试时却出现了错误。
小文很快意识到,她的程序里的变量都是 int
类型的。在大多数机器上,int
类型能表示的最大数为 231−12^{31} - 1231−1,因此只要计算结果超过这个数,她的程序就会出现错误。
由于小文刚刚学会编程,她担心使用 int
计算会出现问题。因此她希望你在 aba^bab 的值超过 109{10}^9109 时,输出一个 -1
进行警示,否则就输出正确的 aba^bab 的值。
然而小文还是不知道怎么实现这份程序,因此她想请你帮忙。
输入格式
输入共一行,两个正整数 a,ba, ba,b。
输出格式
输出共一行,如果 aba^bab 的值不超过 109{10}^9109,则输出 aba^bab 的值,否则输出 -1
。
样例 #1
样例输入 #1
10 9
样例输出 #1
1000000000
样例 #2
样例输入 #2
23333 66666
样例输出 #2
-1
提示
对于 10%10 \%10% 的数据,保证 b=1b = 1b=1。
对于 30%30 \%30% 的数据,保证 b≤2b \le 2b≤2。
对于 60%60 \%60% 的数据,保证 b≤30b \le 30b≤30,ab≤1018a^b \le {10}^{18}ab≤1018。
对于 100%100 \%100% 的数据,保证 1≤a,b≤1091 \le a, b \le {10}^91≤a,b≤109。
解题思路:快速幂+特判
codecodecode
#include<bits/stdc++.h>
using namespace std;;
typedef long long ll;
ll a,b;
int main()
{
scanf("%lld%lld",&a,&b);
ll res=1;
while(b)
{
if(a>1000000000)
{
printf("-1");
return 0;
}
if(b%2==1) res*=a;
if(res>1000000000)
{
printf("-1");
return 0;
}
a*=a;
b/=2;
}
printf("%lld",res);
return 0;
}
T2 [CSP-J 2022] 解密(民间数据)
题目描述
给定一个正整数 kkk,有 kkk 次询问,每次给定三个正整数 ni,ei,din_i, e_i, d_ini,ei,di,求两个正整数 pi,qip_i, q_ipi,qi,使 ni=pi×qin_i = p_i \times q_ini=pi×qi、ei×di=(pi−1)(qi−1)+1e_i \times d_i = (p_i - 1)(q_i - 1) + 1ei×di=(pi−1)(qi−1)+1。
输入格式
第一行一个正整数 kkk,表示有 kkk 次询问。
接下来 kkk 行,第 iii 行三个正整数 ni,di,ein_i, d_i, e_ini,di,ei。
输出格式
输出 kkk 行,每行两个正整数 pi,qip_i, q_ipi,qi 表示答案。
为使输出统一,你应当保证 pi≤qip_i \leq q_ipi≤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+2m = n - e \times d + 2m=n−e×d+2。
保证对于 100%100\%100% 的数据,1≤k≤1051 \leq k \leq {10}^51≤k≤105,对于任意的 1≤i≤k1 \leq i \leq k1≤i≤k,1≤ni≤10181 \leq n_i \leq {10}^{18}1≤ni≤1018,1≤ei×di≤10181 \leq e_i \times d_i \leq {10}^{18}1≤ei×di≤1018
,1≤m≤1091 \leq m \leq {10}^91≤m≤109。
测试点编号 | k≤k \leqk≤ | n≤n \leqn≤ | m≤m \leqm≤ | 特殊性质 |
---|---|---|---|---|
111 | 10310^3103 | 10310^3103 | 10310^3103 | 保证有解 |
222 | 10310^3103 | 10310^3103 | 10310^3103 | 无 |
333 | 10310^3103 | 10910^9109 | 6×1046\times 10^46×104 | 保证有解 |
444 | 10310^3103 | 10910^9109 | 6×1046\times 10^46×104 | 无 |
555 | 10310^3103 | 10910^9109 | 10910^9109 | 保证有解 |
666 | 10310^3103 | 10910^9109 | 10910^9109 | 无 |
777 | 10510^5105 | 101810^{18}1018 | 10910^9109 | 保证若有解则 p=qp=qp=q |
888 | 10510^5105 | 101810^{18}1018 | 10910^9109 | 保证有解 |
999 | 10510^5105 | 101810^{18}1018 | 10910^9109 | 无 |
101010 | 10510^5105 | 101810^{18}1018 | 10910^9109 | 无 |
解题思路:数学题
由题可得:
ni−ei×di−2=pi+qin_i-e_i×d_i-2=p_i+q_ini−ei×di−2=pi+qi(这一点其实题目中也有提示)
所以我们得到:
pi+qi=ni−ei×di−2p_i+q_i=n_i-e_i×d_i-2pi+qi=ni−ei×di−2
pi×qi=nip_i×q_i=n_ipi×qi=ni
接下来用完全平方公式:
(pi+qi)2−4×pi×qi=(pi−qi)2(p_i+q_i)^2-4×p_i×q_i=(p_i-q_i)^2(pi+qi)2−4×pi×qi=(pi−qi)2
将这个式子开方我们就可以得到pi−qip_i-q_ipi−qi,结合我们上面求出的pi+qip_i+q_ipi+qi,就能求出答案了
codecodecode
#include<bits/stdc++.h>
using namespace std;
long long k,n,e,d;
int main()
{
scanf("%lld",&k);
while(k--)
{
int f=0;
scanf("%lld%lld%lld",&n,&e,&d);
long long m=n-e*d+2;
long long p=sqrt(m*m-4*n);
if(p*p!=m*m-4*n) printf("NO\n");
else
{
long long x=(p+m)/2;
long long y=m-x;
printf("%lld %lld\n",min(x,y),max(x,y));
}
}
return 0;
}