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");
}
posted @ 2021-04-06 17:40  QuantAsk  阅读(50)  评论(0编辑  收藏  举报