• 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;
    }
  • 相关阅读:
    Opencv保存摄像头视频&&各种编码器下视频文件占用空间对比
    生活的 tricks
    生活的 tricks
    词汇的积累 —— 反义词、同义词
    词汇的积累 —— 反义词、同义词
    目标跟踪系列十一:Exploiting the Circulant Structure of Tracking-by-detection with Kernels代码思路
    Java中Integer类的方法
    php中 重载(二)
    协方差的意义
    malloc函数具体解释
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9957888.html
Copyright © 2020-2023  润新知