luogu 4884 多少个1 (BSGS)
很有意思的一个签到题 然而考场上并没有切掉
$1111...111=K(mod\;m)$
$10^{x}=9K+1(mod\;m)$
用$BSGS$求解即可
模数爆了$int$,需要快速乘,然而模数是$10^{11}$级别并不是特别大,可以利用位运算进行$O(1)$快速乘
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 4000010 6 #define M1 400010 7 #define ll long long 8 #define dd double 9 #define cll const long long 10 #define inf 23333333333333333ll 11 using namespace std; 12 13 ll K,M,A; 14 struct Hsh{ 15 #define maxn 4000000 16 int head[N1],nxt[M1],val[M1],cte;ll to[M1]; 17 void ins(ll x,int w) 18 { 19 int u=x%maxn; ll v; 20 for(int j=head[u];j;j=nxt[j]) 21 { 22 v=to[j]; 23 if(v==x) return; 24 } 25 cte++; to[cte]=x; nxt[cte]=head[u]; 26 val[cte]=w; head[u]=cte; 27 } 28 int find(ll x) 29 { 30 int u=x%maxn; ll v; 31 for(int j=head[u];j;j=nxt[j]) 32 { 33 v=to[j]; 34 if(v==x) return val[j]; 35 } 36 return -1; 37 } 38 }h; 39 40 inline ll qmul(ll a,ll b){ 41 return ((((a>>25)*b%M)<<25)%M+(a&((1<<25)-1))*b%M)%M; 42 } 43 ll qpow(ll x,ll y) 44 { 45 ll ans=1; 46 while(y){ 47 if(y&1) ans=qmul(ans,x); 48 x=qmul(x,x); y>>=1; 49 }return ans; 50 } 51 52 int main() 53 { 54 scanf("%lld%lld",&K,&M); 55 A=(9ll*K+1)%M; 56 ll sq=sqrt(M),i,pw,now,ans; 57 for(pw=qpow(10ll,sq),now=1,i=1;(i-1)*sq<M;i++) 58 { 59 now=qmul(now,pw); 60 h.ins(now,i); 61 } 62 for(now=A,ans=inf,i=0;i<sq;i++) 63 { 64 pw=h.find(now); 65 if(pw!=-1) ans=min(ans,pw*sq-i); 66 now=qmul(now,10ll); 67 } 68 printf("%lld\n",ans); 69 return 0; 70 }