看起来是构造题但其实是数学题。对于这种数的构造题就去构造一种情况然后算出来。
假设 (a) 有 (n) 位,枚举后面有多少位 (m) ,设 (x = a imes 10^m + b , 2^k mod{ 10^{n+m} } = x) 。
当 (m) 确定,那么 (b) 能取一段 (10^m) 个不同的数,当 (10^m ge 2^{n+m}) 时一定有解。
我们需要做两步:算 (b) ,算 (k) 。
设 (kge n+m) 。所以 (2^{n+m} | 2^k , 2^{n+m}|10^{n+m}) 所以 (2^{n+m} | a imes 10^m + b) 。
同时由于 (5 mid 2^k) ,所以 (5^{n+m} mid 2^k , 5^{n+m} mid a imes 10^m + b) 。
构造 (b=-a imes {10}^{m} mod 2^{n+m}) ,如果 (b) 为 (5) 的倍数就再加上 (2^{n+m}) ,这样 (a imes 10^m +b) 符合条件。(此时还要满足 (10^m ge 2^{n+m}) )
让刚才的同余式子两边除以 (2^{n+m}) 得到 (2^{k-n-m} mod{ 5^{n+m} } = dfrac{a imes 10^m + b}{ 2^{n+m} }) 。
由于 (2) 是 (5^m) 的原根,我们可以构造出 (k) 。
这里不能直接 BSGS 了。但可以一步步归纳构造:
首先暴力出 (d_1) 使得 (2^{d_1} equiv x pmod 5) 。
然后求 (d_i) 使得 (2^{d_i} equiv xpmod {5^i}) 。可以暴力枚举 (d_{i-1}+j imes varphi(5^{i-1}),j=0sim 4) ,一定有一个满足。(这个结论不太会证)
CF 不让用 __int128
,只能用龟速乘了。
#include<bits/stdc++.h>
#define For(i,a,b) for(register int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
#define int long long
using namespace std;
inline int read()
{
char c=getchar();int x=0;bool f=0;
for(;!isdigit(c);c=getchar())f^=!(c^45);
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
if(f)x=-x;return x;
}
inline int mul(int x,int y,int mod){
int res=0;
while(y){
if(y&1)res=(res+x)%mod;
y>>=1,x=(x<<1)%mod;
}return res;
}
inline int qpow(int x,int y,int mod){
int res=1;
while(y){
if(y&1)res=mul(res,x,mod);
y>>=1,x=mul(x,x,mod);
}return res;
}
void work()
{
int a=read(),qwq=a,n=0;
while(qwq)++n,qwq/=10;
for(int pw10=10,m=1;;m++,pw10*=10)
{
int mod=(1ll<<(n+m));
if(pw10<mod) continue;
int b=(-a*pw10%mod+mod)%mod;
if(b%5==0) b+=mod;
if(b>=pw10)continue;
int x=(a*pw10+b)/mod;
int phi=4,pw5=25,res;
For(i,0,4)
if(qpow(2,i,5)==x%5){res=i;break;}
// cout<<"res "<<res<<" "<<x<<endl;
for(int i=2;i<=n+m;++i,phi*=5,pw5*=5){
For(j,0,4)
if(qpow(2,res+phi*j,pw5)==x%pw5){
res+=phi*j;
break;
}
}
res+=m+n;
cout<<res<<endl;
return;
}
}
signed main()
{
int T=read();
while(T--)work();
return 0;
}