CSP-J 2022

T1 [CSP-J 2022] 乘方(民间数据)

题目描述

小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数 aaabbb,求 aba^bab 的值是多少。

aba^babbbbaaa 相乘的值,例如 232^323 即为 333222 相乘,结果为 2×2×2=82 \times 2 \times 2 = 82×2×2=8

“简单!”小文心想,同时很快就写出了一份程序,可是测试时却出现了错误。

小文很快意识到,她的程序里的变量都是 int 类型的。在大多数机器上,int 类型能表示的最大数为 231−12^{31} - 12311,因此只要计算结果超过这个数,她的程序就会出现错误。

由于小文刚刚学会编程,她担心使用 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 2b2
对于 60%60 \%60% 的数据,保证 b≤30b \le 30b30ab≤1018a^b \le {10}^{18}ab1018
对于 100%100 \%100% 的数据,保证 1≤a,b≤1091 \le a, b \le {10}^91a,b109

解题思路快速幂+特判

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×qiei×di=(pi−1)(qi−1)+1e_i \times d_i = (p_i - 1)(q_i - 1) + 1ei×di=(pi1)(qi1)+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_ipiqi

如果无解,请输出 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.indecode/decode2.ans

【样例 #3】

见附件中的 decode/decode3.indecode/decode3.ans

【样例 #4】

见附件中的 decode/decode4.indecode/decode4.ans

【数据范围】

以下记 m=n−e×d+2m = n - e \times d + 2m=ne×d+2

保证对于 100%100\%100% 的数据,1≤k≤1051 \leq k \leq {10}^51k105,对于任意的 1≤i≤k1 \leq i \leq k1ik1≤ni≤10181 \leq n_i \leq {10}^{18}1ni10181≤ei×di≤10181 \leq e_i \times d_i \leq {10}^{18}1ei×di1018
1≤m≤1091 \leq m \leq {10}^91m109

测试点编号k≤k \leqkn≤n \leqnm≤m \leqm特殊性质
11110310^310310310^310310310^3103保证有解
22210310^310310310^310310310^3103
33310310^310310910^91096×1046\times 10^46×104保证有解
44410310^310310910^91096×1046\times 10^46×104
55510310^310310910^910910910^9109保证有解
66610310^310310910^910910910^9109
77710510^5105101810^{18}101810910^9109保证若有解则 p=qp=qp=q
88810510^5105101810^{18}101810910^9109保证有解
99910510^5105101810^{18}101810910^9109
10101010510^5105101810^{18}101810910^9109

解题思路数学题
由题可得
ni−ei×di−2=pi+qin_i-e_i×d_i-2=p_i+q_iniei×di2=pi+qi(这一点其实题目中也有提示)
所以我们得到
pi+qi=ni−ei×di−2p_i+q_i=n_i-e_i×d_i-2pi+qi=niei×di2
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)24×pi×qi=(piqi)2
将这个式子开方我们就可以得到pi−qip_i-q_ipiqi,结合我们上面求出的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;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值