正题
题目链接:https://www.luogu.com.cn/problem/P4884
题目大意
求一个最小的nnn使得nnn个连续的111其在模mmm意义下等于kkk。
6≤m≤1011,0<k<m6\leq m\leq 10^{11},0<k<m6≤m≤1011,0<k<m
解题思路
补一道老题
nnn个连续的111就是10n−19\frac{10^n-1}{9}910n−1所以题目是求
10n−19≡k(modm)\frac{10^n-1}{9}\equiv k(mod\ m)910n−1≡k(mod m)
⇒10n≡9k+1(modm)\Rightarrow 10^n\equiv 9k+1(mod\ m)⇒10n≡9k+1(mod m)
然后BSGS\text{BSGS}BSGS就好了
要开__int128\text{\_\_int128}__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");
}