zoukankan      html  css  js  c++  java
  • bzoj1467 Pku3243 clever Y

    1467: Pku3243 clever Y

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 313  Solved: 181
    [Submit][Status][Discuss]

    Description

    小Y发现,数学中有一个很有趣的式子: X^Y mod Z = K 给出X、Y、Z,我们都知道如何很快的计算K。但是如果给出X、Z、K,你是否知道如何快速的计算Y呢?

    Input

    本题由多组数据(不超过20组),每组测试数据包含一行三个整数X、Z、K(0 <= X, Z, K <= 10^9)。 输入文件一行由三个空格隔开的0结尾。

    Output

    对于每组数据:如果无解则输出一行No Solution,否则输出一行一个整数Y(0 <= Y < Z),使得其满足XY mod Z = K,如果有多个解输出最小的一个Y。

    Sample Input

    5 58 33
    2 4 3
    0 0 0

    Sample Output

    9
    No Solution

    HINT

     

    Source

    ghy

    分析:扩展BSGS.对于P与A不互质的情况,我们就不断地提gcd出来,直到互质.然后换元套用普通的bsgs算法即可.具体的解法:--来自Clove_unique的博客.事实上只需要根据式子就可以用普通的BSGS算法了,求出x-k后,加上k就是x.

         一个思想:从普通算法向扩展算法的延伸,如果由互质版本变成不互质版本,想办法变成互质版本,可以取gcd.一定要是等价变形.在变形的时候要判断无解的情况.

    #include <cstdio>
    #include <cmath>
    #include <map>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    ll a, b, p, block;
    map <ll, ll> m; 
    
    ll gcd(ll a, ll b)
    {
        if (!b)
            return a;
        return gcd(b, a % b);
    }
    
    ll qpow(ll a, ll b)
    {
        ll res = 1;
        while (b)
        {
            if (b & 1)
                res = (res * a) % p;
            a = (a * a) % p;
            b >>= 1;
        }
        return res;
    }
    
    ll exbsgs(ll a, ll b, ll p)
    {
        if (b == 1)
            return 0;
        ll temp = gcd(a, p), cnt = 0, t = 1;
        while (temp != 1)
        {
            if (b % temp != 0)
                return -1;
            cnt++;
            b /= temp;
            p /= temp;
            t = t * (a / temp) % p;
            temp = gcd(a, p);
        }
            m.clear();
            block = sqrt(p);
            ll res = b, ta = qpow(a, block);
            for (ll i = 1; i <= block; i++)
            {
                res = res * a % p;
                m[res] = i;
            }
            for (ll i = 1; i <= block; i++)
            {
                t = t * ta % p;
                if (m[t])
                    return i * block - m[t] + cnt;
            }
        return -1;
    }
    
    int main()
    {
        while (scanf("%lld%lld%lld", &a, &p, &b) && a && b && p)
        {
            ll ans = exbsgs(a % p, b % p, p);
            if (ans != -1)
                printf("%lld
    ", ans);
            else
                puts("No Solution");
        }
    
        return 0;
    }
  • 相关阅读:
    pandas 生成excel
    身份证校验规则
    css 模态框
    python3 打开MySQL时:RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods 报错
    selenium元素定位
    LR的基本知识
    python3的编码报错解决办法
    MySQL的简单条件判断语句
    Java判断一个字符串中包含另一字符串
    使用线程池获取执行结果,CountDownLatch+ThreadPool,FutureTask+ThreadPool 并比较
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7880175.html
Copyright © 2011-2022 走看看