zoukankan      html  css  js  c++  java
  • [bzoj2242][SDOI2011]计算器

    来自FallDream的博客,未经允许,请勿转载,谢谢。


    你被要求设计一个计算器完成以下三项任务:
    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)的最小非负整数。
    1<=y,z,p<=10^9

    第一问快速幂 第二问exgcd 第三问bsgs

    然后bsgs的时候感觉写$y^{ax-b}=z$比较舒服,这样$y^b$可以直接乘到右边

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int n,k,y,z,p,MN;
    ll a,b;
    map<int,int> mp; 
    
    int pow(int x,int k,int mod)
    {
        if(mod==1) return 0;
        int sum=1;
        for(;k;k>>=1,x=1LL*x*x%mod)
            if(k&1) sum=1LL*sum*x%mod;
        return sum;
    } 
    
    int exgcd(int a,int b,ll&x,ll&y)
    {
        if(!b){x=1;y=0;return a;}
        int c=exgcd(b,a%b,x,y);
        ll t=x;x=y;y=t-(a/b)*x;
        return c;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&k)!=EOF)
        {
            if(k==1)
            {
                for(int i=1;i<=n;i++)
                    y=read(),z=read(),p=read(),printf("%d
    ",pow(y,z,p));
            }
            if(k==2)
            {
                for(int i=1;i<=n;i++)
                {
                    y=read(),z=read(),p=read();
                    int c=exgcd(y,p,a,b);
                    if(z%c) puts("Orz, I cannot find x!");
                    else y/=c,z/=c,p/=c,printf("%lld
    ",((a*z/c)%p+p)%p);
                }
            }
            if(k==3)
            {
                for(int i=1;i<=n;i++)
                {
                    mp.clear();
                    y=read();z=read();p=read();y%=p;MN=ceil(sqrt(p));
                    if(!y&&!z)puts("1");else
                    if(!y)puts("Orz, I cannot find x!");
                    else if(p==1) puts("0");
                    else
                    {
                        int times=pow(y,MN,p);bool flag=0;
                        for(int j=0,k=z%p;j<=MN;j++,k=1LL*k*y%p)
                            mp[k]=j;
                        for(int j=1,k=times;j<MN;j++,k=1LL*k*times%p)
                            if(mp[k]) {flag=1,printf("%lld
    ",1LL*j*MN-mp[k]);break;}
                        if(!flag) puts("Orz, I cannot find x!");
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    查找(二)简单清晰的B树、Trie树具体解释
    Java模式(适配器模式)
    程序猿生存定律--交换是职场里一切的根本
    list C++实现
    腾讯面试
    Android4.2.2启动动画前播放视频
    cocos2d0基础篇笔记一
    String.Split()函数
    oracle之表空间(tablespace)、方案(schema)、段(segment)、区(extent)、块(block)
    [一个互联网思想信徒]:今天突破69个听众
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj2242.html
Copyright © 2011-2022 走看看