P4884-多少个1?【BSGS】
正题
题目链接:https://www.luogu.com.cn/problem/P4884
题目大意
求一个最小的\(n\)使得\(n\)个连续的\(1\)其在模\(m\)意义下等于\(k\)。
\(6\leq m\leq 10^{11},0<k<m\)
解题思路
补一道老题
\(n\)个连续的\(1\)就是\(\frac{10^n-1}{9}\)所以题目是求
\[\frac{10^n-1}{9}\equiv k(mod\ m)
\]
\[\Rightarrow 10^n\equiv 9k+1(mod\ m)
\]
然后\(\text{BSGS}\)就好了
要开\(\text{\_\_int128}\)
code
#include<cstdio>
#include<cmath>
#include<map>
#include<cctype>
#define ll __int128
using namespace std;
ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
void print(ll x)
{if(x>9)print(x/10);putchar(48+x%10);return;}
ll k,m,a;
map<ll,ll> hash;
int main()
{
k=read();m=read();k=(k*9+1)%m;
ll q=(ll)sqrt((double)m)+1;
ll val=1;
for(ll j=0;j<q;j++)
{
hash[val*k%m]=j;
val=val*10%m;
}
a=val%m;
if(!a) {
printf("%d",(m==0)?1:-1);
return 0;
}
val=1;
for(ll i=0;i<=q;i++){
ll j=hash.find(val)==hash.end()?-1:hash[val];
if(j>=0&&i*q-j>=0) {
print(i*q-j);
return 0;
}
val=val*a%m;
}
printf("-1");
}