zoukankan      html  css  js  c++  java
  • Luogu P3846 [TJOI2007] 可爱的质数/【模板】BSGS

    题意

    给定 (y,z,p),求最小的正整数 (x) 满足 (y^xequiv zmod p),保证 (p) 是质数。

    ( exttt{Data Range:}2leq y,z<p<^{31})

    题解

    BSGS 裸题。

    这题其实我一年前就做过了,但是现在发现差点背不得 BSGS 了,所以重新写了一遍。

    背 BSGS 其实只要掌握原理就好了。

    首先考虑分块。令 (x=am-b,m=sqrt{p}),那么就有

    [y^{am}equiv zy^bpmod p ]

    注意到由于 (b) 只有 (sqrt{b}) 种取值方法,所以可以将所有可能的 (zy^b) 拿个哈希表存下来。

    然后枚举 (a),暴力查 (y^{am}) 在哈希表里有没有对应的值就好了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef int ll;
    typedef long long int li;
    const ll MAXN=2e5+51;
    unordered_map<ll,ll>hsh;
    ll x,y,MOD,res;
    inline ll read()
    {
        register ll num=0,neg=1;
        register char ch=getchar();
        while(!isdigit(ch)&&ch!='-')
        {
            ch=getchar();
        }
        if(ch=='-')
        {
            neg=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            num=(num<<3)+(num<<1)+(ch-'0');
            ch=getchar();
        }
        return num*neg;
    }
    inline ll qpow(ll base,ll exponent)
    {
        ll res=1;
        while(exponent)
        {
            if(exponent&1)
            {
                res=(li)res*base%MOD;
            }
            base=(li)base*base%MOD,exponent>>=1;
        }
        return res;
    }
    inline ll find(ll x)
    {
        return hsh.find(x)==hsh.end()?-1:hsh[x];
    }
    inline ll BSGS(ll base,ll res)
    {
        ll blk=sqrt(MOD)+1,v=(res%=MOD),x;
        hsh.clear(),base%=MOD;
        for(register int i=0;i<=blk;i++)
        {
            hsh[v]=i,v=(li)v*base%MOD;
        }
        base=qpow(base,blk),v=1;
        if(!base)
        {
            return !res?1:-1;
        }
        for(register int i=0;i<=blk;i++)
        {
            x=find(v),v=(li)v*base%MOD;
            if(x>=0&&i*blk-x>=0)
            {
                return i*blk-x;
            }
        }
        return -1;
    }
    int main()
    {
        MOD=read(),x=read(),y=read(),res=BSGS(x,y);
        res==-1?puts("no solution"):printf("%d
    ",res);
    }
    
  • 相关阅读:
    oracle使用expdp备份数据库
    用Setuptools构建和分发程序包
    C#5.0-原生异步编程方式
    任务并行库
    线程-线程池1
    多线程-3(同步)
    多线程-2(线程同步)
    线程---1
    高性能-GC3
    高性能-GC2
  • 原文地址:https://www.cnblogs.com/Karry5307/p/13489205.html
Copyright © 2011-2022 走看看