2019 cattle off more school fifth generator2 - BSGS && handwriting Hash

topic

Almost original title BZOJ3122 solution to a problem

analysis

First push wave equation, and then classified to remove special case discussed, the rest is of the form $ a ^ i \ equiv b (mod \ p) $ equation BSGS algorithm may be used.

In standard BSGS, the inner and outer layers are circulating $ \ sqrt p $, $ m $ topic query times, $ m \ leq 1000 $, $ p \ leq 10 ^ 9 $, so the total time complexity is $ O (m \ sqrt p) $, barely able to accept. It is said that the use of optimization and read handwritten hash or could live, visible Cls of the code %%%

Think for a moment, because the BSGS divided into two steps, the first step is to establish where $ a $ is a power of the table, but the question is exactly $ a, a set of challenge under the same p $, so this part of the process can be.

Obviously, we should divide this part of the big points, the second step will be lowercase (because certain product),

The divided $ \ sqrt {mp} \ times \ sqrt {\ frac {p} {m}} $ (preceded by pretreatment time period, followed by a per query)

It may be $ \ frac {p} {1000} \ times 1000 $, in short, if the preprocessing section larger.

#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define pb push_back
#define mp make_pair
#define FI first
#define SE second
#define maxn 100000
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef double db;
  
int mod;
int m=1000;
  
const int M=12000005;
int hs[M],head[M],nxt[M],id[M],top;
void insert(int x,int y)
{
    int k=x%M;
    hs[top]=x,id[top]=y,nxt[top]=head[k],head[k]=top++;
}
int find(int x)
{
    int k=x%M;
    for(int i=head[k];i!=-1;i=nxt[i]) if(hs[i]==x) return id[i];
    return -1;
}
  
int BSGS(int a,int b,int n)
{
    if(b==1) return 0;
    ll p=1;
    int ans=inf;
    rep(i,0,m)
    {
        int id=find(1ll*p*b%n);
        if(id!=-1) ans=min(ans,id-i);
        p=p*a%mod;
    }
    if(ans==inf) return -1;
    return ans;
}
  
ll qp(ll a,ll k)
{
    ll res=1;
    while(k)
    {
        if(k&1) res=res*a%mod;
        a=a*a%mod;
        k>>=1;
    }
    return res;
}
ll _inv(ll x) {return qp(x,mod-2);}
  
int main()
{
    int CAS; scanf("%d",&CAS);
    while(CAS--)
    {
        ll N; int x0,a,b; scanf("%lld%d%d%d%d",&N,&x0,&a,&b,&mod);
        memset(head,-1,sizeof head); top=1;
  
        int bn=(mod+m-1)/m;
        int aA=qp(a,m),pw=aA;
        rep(i,1,bn)
        {
            if(find(pw)==-1) insert(pw,i*m);
            pw=1ll*pw*aA%mod;
        }
        int Q; scanf("%d",&Q);
        while(Q--)
        {
            int v; scanf("%d",&v);
            if(a==0)
            {
                if(v==x0) puts("0");
                else if(v==b)
                {
                    if(N==1) puts("-1");
                    else puts("1");
                }
                else puts("-1");
            }
            else if(a==1)
            {
                if(b==0)
                {
                    if(v==x0) puts("0");
                    else puts("-1");
                }
                else
                {
                    ll n=1ll*(v+mod-x0)*_inv(b)%mod;
                    if(n>=N) puts("-1");
                    else printf("%lld\n",n);
                }
            }
            else
            {
                v=(1ll*(a-1)*v+b)%mod;
                int X=(1ll*(a-1)*x0+b)%mod;
                if(X==0)
                {
                    if(v==0) puts("0");
                    else puts("-1");
                }
                else
                {
                    v=1ll*v*_inv(X)%mod;
                    if(v==0) puts("-1");
                    else
                    {
                        int n=BSGS(a,v,mod);
                        if(n>=N) puts("-1");
                        else printf("%d\n",n);
                    }
                }
            }
        }
    }
    return 0;
}

 

 

Reference Links: https://ac.nowcoder.com/acm/contest/view-submission?submissionId=41008097

 

Guess you like

Origin www.cnblogs.com/lfri/p/11286172.html