CF913G Power Substring 数论
看起来是构造题但其实是数学题。对于这种数的构造题就去构造一种情况然后算出来。
假设 \(a\) 有 \(n\) 位,枚举后面有多少位 \(m\) ,设 \(x = a\times 10^m + b , 2^k \bmod{ 10^{n+m} } = x\) 。
当 \(m\) 确定,那么 \(b\) 能取一段 \(10^m\) 个不同的数,当 \(10^m \ge 2^{n+m}\) 时一定有解。
我们需要做两步:算 \(b\) ,算 \(k\) 。
设 \(k\ge n+m\) 。所以 \(2^{n+m} | 2^k , 2^{n+m}|10^{n+m}\) 所以 \(2^{n+m} | a\times 10^m + b\) 。
同时由于 \(5 \nmid 2^k\) ,所以 \(5^{n+m} \nmid 2^k , 5^{n+m} \nmid a\times 10^m + b\) 。
构造 \(b=-a\times {10}^{m} \bmod 2^{n+m}\) ,如果 \(b\) 为 \(5\) 的倍数就再加上 \(2^{n+m}\) ,这样 \(a\times 10^m +b\) 符合条件。(此时还要满足 \(10^m \ge 2^{n+m}\) )
让刚才的同余式子两边除以 \(2^{n+m}\) 得到 \(2^{k-n-m} \bmod{ 5^{n+m} } = \dfrac{a\times 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 x\pmod {5^i}\) 。可以暴力枚举 \(d_{i-1}+j\times \varphi(5^{i-1}),j=0\sim 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;
}