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;
    }
  • 相关阅读:
    Median Value
    237. Delete Node in a Linked List
    206. Reverse Linked List
    160. Intersection of Two Linked Lists
    83. Remove Duplicates from Sorted List
    21. Merge Two Sorted Lists
    477. Total Hamming Distance
    421. Maximum XOR of Two Numbers in an Array
    397. Integer Replacement
    318. Maximum Product of Word Lengths
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7880175.html
Copyright © 2011-2022 走看看