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