[bzoj2242][bsgs]计算器

本文介绍了一个计算器程序的设计与实现,主要解决三种类型的数学问题:1. 计算Y^Z Mod P的值;2. 寻找满足xy≡Z (mod P)的最小非负整数x;3. 寻找满足Y^x≡Z (mod P)的最小非负整数x。针对这三种情况,文章提供了具体的算法思路,包括快速幂算法及baby-step giant-step算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2242: [SDOI2011]计算器

Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 5035 Solved: 1914
[Submit][Status][Discuss]
Description

你被要求设计一个计算器完成以下三项任务:
1、给定y,z,p,计算Y^Z Mod P 的值;
2、给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数;
3、给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数。
Input

输入包含多组数据。

第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
以下行每行包含三个正整数y,z,p,描述一个询问。
Output

对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。
Sample Input

【样例输入1】

3 1

2 1 3

2 2 3

2 3 3

【样例输入2】

3 2

2 1 3

2 2 3

2 3 3

【数据规模和约定】

对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。
Sample Output

【样例输出1】

2

1

2

【样例输出2】

2

1

0

HINT

Source

第一轮day1

sol:

1,2问快速幂,3bsgs
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
int n,m;
inline int read()
{
    char c;
    int res,flag=0;
    while((c=getchar())>'9'||c<'0') if(c=='-')flag=1;
    res=c-'0';
    while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0';
    return flag?-res:res;
}
int x,y,z,ty;
inline int ksm(int x,int y,int z)
{
    int res=1;
    while(y)
    {
        if(y&1) res=(ll)res*x%z;
        x=(ll)x*x%z;
        y>>=1;
    }
    return res;
}
map<int,int> hash; 
inline void bsgs()
{
    y%=z;
    if (x==0&&y==0) {printf("1\n");return;}  
    if (x==0&&y!=0) {printf("Orz, I cannot find x!\n");return;}  
    hash.clear();
    int q=ceil(sqrt(z)),p=y;
    for(int j=1;j<=q;++j)
    {
        p=(ll)p*x%z;
        if(!hash[p])
        hash[p]=j;
    }
    p=ksm(x,q,z);
    int tmp=1;
    for(int i=1;i<=q;++i)
    {
        tmp=(ll)tmp*p%z;
        if(hash[tmp])
        {
            printf("%d\n",i*q-hash[tmp]);
            return;
        }
    }
    printf("Orz, I cannot find x!\n");
}
inline void solve()
{
    x=read();
    y=read();
    z=read();
    x%=z;
    if(ty==1) printf("%d\n",ksm(x,y,z)); 
    else if(ty==2)
    {
        y%=z;
        if(!x&&y) printf("Orz, I cannot find x!\n");
        else printf("%d\n",(ll)y*ksm(x,z-2,z)%z);
    }
    else bsgs(x,y,z);
}
int main()
{
//  freopen("calc.in","r",stdin);
//  freopen("calc.out","w",stdout);
    int T=read();
    ty=read();
    while(T--) solve();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值