• Contest 20140923 登月计划 BabyStepGaintStep


    登月计划

    总时间限制: 
    40000ms
     
    内存限制: 
    256000kB
    描述

    HJA在和学弟学数学,于是便有了一道非常简单的数学题:求满足 的最小自然数x。

    输入
    输入数据一行三个正整数a、b、p,我们保证p是一个质数。
    输出
    一行一个整数代表最小的自然数x,如果不存在这样的x输出-1。
    样例输入
    2 1 3
    样例输出
    0
    提示
    对于30%的数据,1≤p≤1000。
    对于100%的数据,1≤a,b<p≤10^12。< dd="">
    来源
    zhonghaoxi

      BabyStepGiantStep

      這道題考場上卡在了求解 a*x == b (mod p) 這一步上。

      解a*x == b (mod p) 方法爲 

        a * b^(-1) * x == 1 (mod p)

        x= (a*b^(-1))^(-1)

      然而這樣還是要TLE,觀察發現其中每次求值時a總會乘上一個常數t,則x每次乘上t^(-1)就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    #define MAXN 1100000
    #define MAXV MAXN*2
    #define MAXE MAXV*2
    #define INF 0x3f3f3f3f
    #define INFL 0x3f3f3f3f3f3f3f3fLL
    #define VAL1 1000007
    #define PROB "braveheart"
    typedef long long qword;
    qword base,res,mod;
    
    struct Edge
    {
            qword t,v;
            Edge *next;
    }E[MAXE],*V[VAL1+1];
    int tope=-1;
    void addedge(int x,qword y,qword z)
    {
            E[++tope].t=y;
            E[tope].v=z;
            E[tope].next=V[x];
            V[x]=&E[tope];
    }
    inline qword multi(qword x,qword y)
    {
            qword ret=0;
            if (y<0)y=-y,x=-x;
            while (y)
            {
                    if (y&1)ret=(ret+x)%mod;
                    x=(x+x)%mod;
                    y>>=1;
            }
            return ret;
    }
    qword pow_mod(qword x,qword y,qword mod)
    {
            qword ret=1;
            while (y)
            {
                    if (y&1)ret=multi(ret,x);
                    x=multi(x,x);
                    y>>=1;
            }
            return ret;
    }
    
    int main()
    {
            freopen(PROB".in","r",stdin);
            freopen(PROB".out","w",stdout);
            int i;
            qword x,y,z;
            scanf(LL LL LL,&base,&res,&mod);
            int sb=ceil(sqrt(mod-1));
            //baby step
            x=1;
            for (i=0;i<sb;i++)
            {
                    addedge(x%VAL1,i,x);
                    x=multi(x,base);
            }
            qword val1;
            val1=pow_mod(base,sb,mod);
            qword a_i=1; 
            Edge *ne;
            bool flag=false;
            qword t;
            x=res%mod;
            y=pow_mod(val1,mod-2,mod);
            for (i=0;i<=sb;i++)
            {
                    for (ne=V[x%VAL1];ne;ne=ne->next)
                    {
                            if (ne->v==x)
                            {
                                    flag=true;
                                    t=ne->t;
                            }
                    }
                    if (flag)
                    {
                            printf(LL "
    ",(qword)i*sb+t);
                            return 0;
                    }
                    x=multi(x,y);
            }
            printf("-1
    ");
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    phalcon——HTTP 请求
    phalcon——闪存消息
    phalcon——验证
    Java 字符串分隔 split
    Eclipse "R cannot be resolved"问题
    Android CountDownTimer 类实现倒计时
    Eclipse 打开时“发现了以元素'd:skin'”开头的无效内容。此处不应含有子元素
    Android Studio 设置/更改 SDK 路径
    Android 开发使用自定义字体
    Android Studio "ADB not responding"
  • 原文地址:https://www.cnblogs.com/mhy12345/p/3991565.html
Copyright © 2020-2023  润新知