zoukankan      html  css  js  c++  java
  • BZOJ 2242: [SDOI2011]计算器

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

    第一问快速幂

    第二问exgcd

    第三问BSGS,好麻烦我就先略

    为啥叫baby step giant step,我其实不是很懂

    求(y^x = z(mod~p))设(x=km+i)[y^{km}*y^iequiv z](y^iequiv z*ine(y^{km}))(逆元)

    用费马小定理显然可得(ine(y^m)equiv y^{p-1-m})设其为T

    [ine(y^{km})equiv ine(y^{(k-1)m})*T]

    把[y^i(0<=i<=m)]放入hash或者map

    然后枚举k,查询[z*ine(y^{km})]

    显然m取(sqrt p)复杂度比较优秀。。

    解释部分转自黄学长

    屠龙宝刀点击就送

    #include <ctype.h>
    #include <cstdio>
    #include <cmath>
    #include <map>
    using namespace std;
    typedef long long LL;
    map<LL,int>q;
    void read(int &x)
    {
        x=0;bool f=0;
        register char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=1;
        for(; isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        x=f?(~x)+1:x;
    }
    inline LL ksm(int a,int b,int c)
    {
        LL base=a,r=1%c;
        while(b)
        {
            if(b&1) r=(r*base)%c;
            base=(base*base)%c;
            b>>=1;
        }
        return r;
    }
    int gcd(int a,int b) {return a%b==0?b:gcd(b,a%b);}
    void exgcd(int a,int b,int &x,int &y)
    {
        if(b==0)
        {
            x=1;y=0;
            return;
        }
        exgcd(b,a%b,x,y);
        int tmp=x;
        x=y;
        y=tmp-(a/b)*y;
    }
    int T,L;
    int main()
    {
        read(T);
        read(L);
        for(int y,z,p;T--;)
        {
            read(y);
            read(z);
            read(p);
            switch(L)
            {
                case 1:
                {
                    printf("%d
    ",ksm(y,z,p));
                    break;
                }
                case 2:
                {
                    int m,n;
                    p=-p;
                    int k=gcd(y,p);
                    if(z%k) 
                        printf("Orz, I cannot find x!
    ");
                    else
                    {
                        y/=k;z/=k;p/=k;
                        exgcd(y,p,m,n);
                        m=(LL)m*z%p;
                        for(;m<0;m+=p);
                        printf("%d
    ",m);
                    }
                    break;
                }
                case 3:
                {
                    if(y%p==0&&z==0) printf("1
    ");
                    else if(y%p==0) printf("Orz, I cannot find x!
    ");
                    else 
                    {
                        q.clear();
                        bool flag=false;
                        LL t=1,m=ceil(sqrt(p));
                        q[1]=m+1;
                        for(LL i=1;i<m;i++)
                        {
                            t=t*y%p;
                            if(!q[t]) q[t]=i;
                        }
                        t=ksm(y,p-m-1,p);LL in=1;
                        for(LL k=0;k<m;k++)
                        {
                            int ans=z*in%p;
                            if(q[ans])
                            {
                                int v=q[ans];
                                if(v==m+1) v=0;
                                printf("%lld
    ",k*m+v);
                                flag=true;
                                break;
                            }
                            in=in*t%p;
                        }
                        if(!flag) printf("Orz, I cannot find x!
    ");
                    }
                    break;
                }
            }
        }
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    tfs+git
    fis3 部署手册
    git +vs2017 操作手册+目前工作流程图
    Git 分支策略
    git 分回滚后无法合并代码问题
    git 拉取远程分支到本地并建立关联关系
    mysql查看数据库大小或者表大小
    centos7.4安装高可用(haproxy+keepalived实现)kubernetes1.6.0集群(开启TLS认证)
    centos7.4安装kubernetes1.6.0(开启TLS认证)
    Centos搭建http代理服务器(无密码验证)
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7268715.html
Copyright © 2011-2022 走看看