• BZOJ 2242


    2242: [SDOI2011]计算器

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 5142  Solved: 1964
    [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

     
    此题做法多种多样(我指的是第二问hhh)
    1:quickpow ; 3:bsgs 无疑问
    2:可以用exgcd,也可以直接用一下逆元,毕竟p是素数。
    为了复习exgcd,我决定用比较烦的exgcd做
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<complex>
    #include<map>
    #include<cstring>
    #define ll long long
    using namespace std;
    ll read()
    {
        ll x=0,f=1;char s=getchar();
        while(s<'0' || s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0' && s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    ll y,z,p;
    ll pow(ll a,ll x)
    {
        ll ans=1;
        for(;x>0;x>>=1,a=a*a%p)
            if(x&1)ans=ans*a%p;
        return ans%p;
    }
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(b==0){x=1;y=0;return a;}
        ll q=exgcd(b,a%b,y,x);y-=(a/b)*x;
        return q;
    }
    ll T,K;
    map<ll,ll>m;
    void bsgs(ll a,ll b,ll p)
    {
        m.clear();
        if(a%p==0 && b%p==0){printf("0
    ");return;}
        if(a%p==0 && b%p!=0){printf("Orz, I cannot find x!
    ");return;}
        
        ll x=b%p,s=ceil(sqrt(p));m[x]=0;
        //printf("%lld %lld
    ",s,x);
        for(int i=1;i<=s;i++){x=(x*a)%p;m[x]=i;/*printf("%d %lld
    ",i,x);*/}    
        ll t=pow(a,s);x=1;
        for(int i=1;i<=s;i++)
        {
            x=(x*t)%p;
            //printf("%lld ",x);
            if(m[x])
            {
                ll ans=i*s-m[x];
                printf("%lld
    ",(ans%p+p)%p);
                return;
            }
        }
        printf("Orz, I cannot find x!
    ");
    }
    int main()
    {
        T=read(),K=read();
        while(T--)
        {
            y=read(),z=read(),p=read();
            if(K==1)printf("%lld
    ",pow(y,z));
            if(K==2)
            {
                ll a,b,d;
                d=exgcd(y,p,a,b);
                if(z%d!=0)printf("Orz, I cannot find x!
    ");
                else
                {
                    ll ans=(z/d)*a,mod=p/d;
                    ans=(ans%mod+mod)%mod;
                    printf("%lld
    ",ans%p);
                }
            }
            if(K==3)bsgs(y,z,p);
        }
        return 0;
    }

     噢对了,小心特判!!

  • 相关阅读:
    #线段树,矩阵乘法#LOJ 3264「ROIR 2020 Day 2」海报
    #线段树#洛谷 4428 [BJOI2018]二进制
    #Trie#洛谷 7717 「EZEC-10」序列
    shell脚本生成双色球号码
    k8s的tomcat多pod session会话保持配置
    国产系统优麒麟系统使用
    grdi报错--grid的asm磁盘丢失处理方法
    centos7上安装oracle的sqlplus客户端
    linux挂载
    linux占用100%cpu的java处理
  • 原文地址:https://www.cnblogs.com/fdfzhyf/p/8723648.html
Copyright © 2020-2023  润新知