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

    这个题就是把三个数论基础合在了一起,算是一道比较全面的题.

    1的时候就是快速幂

    2的时候是exgcd求逆元,特殊的,只有两数互质才有逆元.

    3就是bsgs啦,还是不太熟

    题干:

    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”之间有一个空格。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<map>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;i++)
    #define lv(i,a,n) for(register int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    #define int long long
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int t,k;
    map <int,int> mp;
    void work1(int y,int z,int p)
    {
        int tot = 1;
        while(z)
        {
            if(z & 1)
            {
                tot *= y;
                tot %= p;
            }
            y *= y;
            y %= p;
            z >>= 1;
        }
        printf("%lld
    ",tot);
    }
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return a;
        }
        int t = exgcd(b,a % b,y,x);
        y -= (a / b * x);
        return t;
    }
    void work2(int y,int z,int p)
    {
        int x,f;
        // z %= p;
        int d = exgcd(y,p,x,f);
        if(d != 1)
        {
            printf("Orz, I cannot find x!
    ");
            return;
        }
        x = (x % p + p) % p;
        x = (x * z) % p;
        /*if(now == p)
        printf("Orz, I cannot find x!");
        else*/
        printf("%lld
    ",x);
    }
    int qpow(int a,int b,int p)
    {
        int tot = 1;
        while(b)
        {
            if(b & 1)
            {
                tot *= a;
                tot %= p;
            }
            a *= a;
            a %= p;
            b >>= 1;
        }
        return tot;
    }
    void work3(int a,int b,int p)
    {
        if(a % p == 0)
        {
            printf("Orz, I cannot find x!
    ");
            return;
        }
        mp.clear();
        int m = ceil(sqrt(p));
        int now = b % p,ans;
        mp[now] = 0;
        duke(i,1,m)
        {
            now = (now * a) % p;
            mp[now] = i;
        }
        int t = qpow(a,m,p);
        now = 1;
        int ok = 1;
        duke(i,1,m)
        {
            now = (now * t) % p;
            if(mp[now])
            {
                ans = i * m - mp[now];
                printf("%lld
    ",(ans % p + p) % p);
                ok = 0;
                break;
            }
        }
        if(ok == 1)
        printf("Orz, I cannot find x!
    ");
    }
    main()
    {
        read(t);read(k);
        //cout<<t<<endl;
        duke(i,1,t)
        {
            int y,z,p;
            read(y);read(z);read(p);
            if(k == 1)
            {
                work1(y,z,p);
            }
            else if(k == 2)
            {
                work2(y,z,p);
            }
            else if(k == 3)
            {
                work3(y,z,p);
            }
            //cout<<i<<" "<<t<<endl;
        }
        return 0;
    }
  • 相关阅读:
    html 上传图片前预览
    php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
    php 计算 pdf文件页数
    php 获取半年内每个月的订单数量, 总价, 月份
    php 获取两个数组之间不同的值
    小程序支付功能
    关于nginx的Job for nginx.service failed because the control process exited with error code.错误
    linux 安装 Apollo
    MongoDB待续。。。
    ABP vNext...待续
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9957888.html
Copyright © 2011-2022 走看看