zoukankan      html  css  js  c++  java
  • 【EX_BSGS】BZOJ1467 Pku3243 clever Y

    1467: Pku3243 clever Y

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 425  Solved: 238
    [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 <= 109)。 输入文件一行由三个空格隔开的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

    题解

    EX_BSGS模板题

    思路懒得写了

    代码

    //by 减维
    #include<set>
    #include<map>
    #include<queue>
    #include<ctime>
    #include<cmath>
    #include<bitset>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    #define il inline
    #define rg register
    #define db double
    #define mpr make_pair
    #define maxn
    #define inf (1<<30)
    #define eps 1e-8
    #define pi 3.1415926535897932384626L
    using namespace std;
    
    inline int read()
    {
        int ret=0;bool fla=0;char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-'){fla=1;ch=getchar();}
        while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
        return fla?-ret:ret;
    }
    
    ll x,y,p;
    map<ll,ll> mp;
    
    ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
    
    ll ksm(ll x,ll y,ll p)
    {
        ll ret=1;x%=p;
        for(;y;y>>=1,x=x*x%p)
            if(y&1) ret=ret*x%p;
        return ret;
    }
    
    ll exbsgs(ll x,ll y,ll p)
    {
        x%=p;y%=p;
        if(!x&&!y) return 1;
        if(y==1) return 0;
        if(!x) return -1;
        ll t,d=1,k=0;
        while((t=gcd(p,x))!=1)
        {
            if(y%t) return -1;
            y/=t,p/=t,d=d*x/t%p,k++;
            if(d==y) return k;
        }
        mp.clear();
        ll m=sqrt(p+0.5);
        ll o=y;
        for(int i=0;i<=m;++i,o=o*x%p)
            if(!mp.count(o)) mp[o]=i;
        ll tmp=ksm(x,m,p);
        for(int i=1;i<=m;++i)
        {
            d=d*tmp%p;
            if(mp.count(d)) return ((i*m-mp[d])%p+k+p)%p;
        }
        return -1;
    }
    
    int main()
    {
        while(1)
        {
            scanf("%lld%lld%lld",&x,&p,&y);
            if(!x&&!y&&!p) break;
            ll ans=exbsgs(x,y,p);
            if(ans==-1) printf("No Solution
    ");
            else printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    算法导论之贪心算法
    编程过程中遇到的一些细节
    c++11和c99
    面试总结(YY一面)
    python(17):字典
    python(16):元组
    python(15):练习题
    python(14):列表
    python(13):字符串
    python(12):练习题
  • 原文地址:https://www.cnblogs.com/rir1715/p/8581778.html
Copyright © 2011-2022 走看看