题目
给定整数KKK和质数mmm,求最小的正整数NNN,使得11⋯1(N个1)≡K(modm)11\cdots1(N个1)\equiv K \pmod m11⋯1(N个1)≡K(modm)
分析
两边同乘9再加1得到
10n≡K∗9+1(modm)10^n\equiv K*9+1\pmod m10n≡K∗9+1(modm)
那么就是BSGS模板了
代码
#include <cstdio>
#include <cctype>
#include <cmath>
#include <tr1/unordered_map>
#define rr register
using namespace std;
using namespace tr1;
typedef long long ll;
const ll trans=33554432;
inline void print(ll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline ll mo(ll a,ll b,ll mod){return a+b>=mod?a+b-mod:a+b;}
inline ll mul(ll a,ll b,ll mod){return mo(a*(b>>25)%mod*trans%mod,a*(b&(trans-1))%mod,mod);}
inline ll bsgs(ll a,ll b,ll mod){
unordered_map<ll,ll>hash;
rr int t=(int)sqrt(mod)+1; rr ll t1=1;
for (rr ll j=0;j<t;++j)
hash[mul(b,t1,mod)]=j,t1=mul(t1,a,mod);
a=t1,t1=1;
if (!a) return !b?1:-1;
for (rr int i=0;i<=t;++i){
rr int j=hash.find(t1)==hash.end()?-1:hash[t1];
if (j>=0&&1ll*i*t>=j) return 1ll*i*t-j;
t1=mul(t1,a,mod);
}
return -1;
}
signed main(){
rr ll n,mod;
scanf("%lld%lld",&n,&mod);
print(bsgs(10,(9*n+1)%mod,mod));
return 0;
}
upd:8.6
突然发现unordered_map太慢了,改成了手写哈希
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#define rr register
using namespace std;
const int p=397337;
typedef long long ll;
struct hash{
struct node{int y; long long w; int next;}e[p]; int hs[p],tot;
inline void clear(){memset(hs,0,sizeof(hs)); tot=0;}
inline void add(int x,ll w){e[++tot]=(node){x,w%p,hs[w%p]},hs[w%p]=tot;}
inline signed locate(ll x){
for (rr int j=hs[x%p];j;j=e[j].next)
if (e[j].w==x) return e[j].y;
return -1;
}
}h;
inline void print(ll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline ll mo(ll a,ll b,ll mod){return a+b>=mod?a+b-mod:a+b;}
inline ll mul(ll a,ll b,ll mod){return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod;}
inline ll bsgs(ll a,ll b,ll mod){
h.clear();
rr int t=sqrt(mod)+1; rr ll t1=1;
for (rr ll j=0;j<t;++j)
h.add(j,mul(t1,b,mod)),t1=mul(t1,a,mod);
a=t1,t1=1;
if (!a) return !b?1:-1;
for (rr int i=0;i<=t;++i){
rr int j=h.locate(t1);
if (j>=0&&1ll*i*t>=j) return 1ll*i*t-j;
t1=mul(t1,a,mod);
}
return -1;
}
signed main(){
rr ll n,mod;
scanf("%lld%lld",&n,&mod);
print(bsgs(10,(9*n+1)%mod,mod));
return 0;
}