• 计算器(bzoj 2242)


    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
    /*
      Type1:快速幂
      Type2:扩展欧几里得
      Type3:BSGS 
    */
    #include<cstdio>
    #include<iostream>
    #include<map>
    #include<cmath>
    #define lon long long
    using namespace std;
    int Q,op;lon A,B,C;
    map<lon,int> hash;
    lon poww(lon a,lon b){
        lon base=a,r=1;
        while(b){
            if(b&1) r*=base;r%=C;
            base*=base;base%=C;
            b>>=1;
        }
        return r;
    }
    lon exgcd(lon a,lon b,lon &x,lon &y){
        if(!b) {
            x=1;y=0;return a;
        }
        lon r=exgcd(b,a%b,x,y);
        lon t=x;x=y;y=t-a/b*y;
        return r;
    }
    void work3(){
        hash.clear();
        if(A%C==0){
            printf("Orz, I cannot find x!
    ");
            return;
        }
        lon m=ceil(sqrt(C)),ans;
        for(int i=0;i<=m;i++){
            if(!i){
                ans=B%C;hash[ans]=i;
                continue;
            }
            ans=(ans*A)%C;hash[ans]=i;
        }
        ans=1;lon t=poww(A,m);bool fl=false;
        for(int i=1;i<=m;i++){
            ans=(ans*t)%C;
            if(hash[ans]){
                ans=i*m-hash[ans];
                ans=(ans+C+C)%C;
                printf("%lld
    ",ans);
                fl=true;
                break;
            }
        }
        if(!fl) printf("Orz, I cannot find x!
    ");
    }
    void work2(){
        lon x,y,vgcd;
        vgcd=exgcd(A,C,x,y);
        if(B%vgcd) {
            printf("Orz, I cannot find x!
    ");
            return;
        }
        x=x*B/vgcd;
        lon mod=C/vgcd;
        x=((x%mod)+mod)%mod;
        printf("%lld
    ",x);
    }
    void work1(){
        printf("%lld
    ",poww(A,B));
    }
    int main(){
        scanf("%d%d",&Q,&op);
        while(Q--){
            scanf("%lld%lld%lld",&A,&B,&C);
            if(op==1) work1();
            if(op==2) work2();
            if(op==3) work3();
        }
        return 0;
    }
  • 相关阅读:
    BTC比特币全节点部署
    redis缓存层实现redission
    thinkphp5日志文件权限的问题
    MYSQL查两个经纬度之间的直线距离,计算出的单位:米
    thinkphp 建单独的日志目录
    VSCode远程连接Linux服务器
    Linux smb 的挂载和取消挂载及解决类似umount target is busy挂载盘卸载不掉问题
    System limit for number of file watchers reached
    JavaScript 字符串方法
    Linux下常用压缩 解压命令和压缩比率对比
  • 原文地址:https://www.cnblogs.com/harden/p/6512358.html
Copyright © 2020-2023  润新知