• bzoj 2242: [SDOI2011]计算器 BSGS+快速幂+扩展欧几里德


    2242: [SDOI2011]计算器

    Time Limit: 10 Sec  Memory Limit: 512 MB
    [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
    思路:1:裸快速幂;
       2:y*x+p*k=z,解方程;
       3:BSGS
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pi (4*atan(1.0))
    #define eps 1e-14
    const int N=2e5+10,M=4e6+10,inf=1e9+10,mod=1e9+7;
    const ll INF=1e18+10;
    #define MOD 100000
    int hs[MOD],head[MOD],nex[MOD],id[MOD];
    int top;
    void Insert(int x,int y)
    {
        int k = x%MOD;
        hs[top] = x, id[top] = y, nex[top] = head[k], head[k] = top++;
    }
    int Find(int x)
    {
        int k = x%MOD;
        for(int i = head[k]; i; i = nex[i]) if(hs[i] == x) return id[i];
        return -1;
    }
    int BSGS(int a,int b,int n)
    {
        a%=n;
        if(!a&&!b){return 1;}
        if(!a){return -1;}
        memset(head,0,sizeof(head));
        top = 1;
        if(b == 1)return 0;
        int m = sqrt(n*1.0), j;
        long long x = 1, p = 1;
        for(int i = 0; i < m; ++i, p = p*a%n)Insert(p*b%n,i);
        for(long long i = m; ; i += m)
        {
            if( (j = Find(x = x*p%n)) != -1 )return i-j;
            if(i > n)break;
        }
        return -1;
    }
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0)
        {
            x=1;y=0;
            return a;
        }
        int r=exgcd(b,a%b,x,y);
        int t=x;x=y;y=t-a/b*y;
        return r;
    }
    int quick(ll x,int y,int mod)
    {
        ll ans=1;
        while(y)
        {
            if(y&1)ans=ans*x,ans%=mod;
            x*=x;
            x%=mod;
            y>>=1;
        }
        return ans;
    }
    int main()
    {
        int T,k;
        scanf("%d%d",&T,&k);
        while(T--)
        {
            int a,b,n;
            scanf("%d%d%d",&a,&b,&n);
            if(k==1)
            printf("%d
    ",quick(1LL*a,b,n));
            else if(k==2)
            {
                int x,y;
                int gcd=exgcd(a,n,x,y);
                x=(x%n+n)%n;
                if(b%gcd!=0)
                printf("Orz, I cannot find x!
    ");
                else
                printf("%lld
    ",(1LL*x*(b/gcd))%n);
            }
            else
            {
                int ans=BSGS(a,b,n);
                if(ans==-1)
                printf("Orz, I cannot find x!
    ");
                else
                printf("%d
    ",ans%mod);
            }
        }
        return 0;
    }
  • 相关阅读:
    关于使用sudo找不到环境变量的问题
    HDFS修改副本数,并生效。
    Linux创建用户,SFTP只允许访问指定目录
    Docker 技术系列之安装Redis单机版和集群版
    Docker 技术系列之安装多版本Mysql5.6和Mysql5.7
    Docker 技术系列之安装Docker Desktop for Mac
    第五章 Mac系统软件-安装Java Web开发环境基本软件
    第四章 感受Mac之美-效率提高从操作快捷键开始
    第三章 感受Mac之美-万里挑一的装机必备软件
    第二章 感受Mac 之美-惊艳从Mac 外设开始,一周后的使用感受
  • 原文地址:https://www.cnblogs.com/jhz033/p/6019804.html
Copyright © 2020-2023  润新知