题解 luogu9月月赛 签到题
题解 luogu9月月赛 签到题
题意
给定整数K和质数m,求最小的正整数N,使得 \(111\cdots11(N个1)\equiv K \pmod m\)
说人话:就是 111...1111 mod m =K
解法
原式变为:
\(\frac{10^n-1}{9} \equiv k \pmod m\)
即:
\(10^n \equiv 9*k+1 \pmod m\)
然后BSGS就可以了。
ps:如果不懂BSGS的同学可以去看这两篇博客,讲的挺好的。
https://blog.csdn.net/zzkksunboy/article/details/73162229
https://blog.csdn.net/clover_hxy/article/details/50683832
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>
#include <vector>
#include <queue>
#include <map>
#define INF 2139062143
#define MAX 0x7ffffffffffffff
#define del(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
template<typename T>
inline void read(T&x)
{
    x=0;T k=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
}
map<ll,ll> Map;
ll mul(ll x,ll y,ll mod) {
	return ((x*y-(ll)(((long double)x*y+0.5)/mod)*mod)+mod)%mod;
}
ll poww(ll a,ll b,ll mod) {
	ll ans=1;
	while(b) {
		if(b&1) ans=mul(ans,a,mod);
		a=mul(a,a,mod);
		b>>=1;
	}
	return ans;
}
ll BSGS(ll a,ll b,ll p) {
	ll temp,m=ceil(sqrt(p));
	if(a%p==0&&b!=0) return -1;
	if(a%p==0&&b==0) return 1;
	for(ll i=0;i<=m;i++) {
		if(!i) {temp=b;Map[temp]=i;continue;}
		temp=mul(temp,a,p);
		Map[temp]=i;
	}
	temp=1ll;ll k=poww(a,m,p);
	for(ll i=1;i<=m;i++) {
		temp=mul(temp,k,p);
		if(Map[temp]) {
			return (mul(i,m,p)-Map[temp]%p+p)%p;
		}
	}
	return -1;
}
ll a=10,m,b;
int main()
{
	read(b),read(m);
	b=(b*9+1)%m;
	printf("%lld\n",BSGS(a,b,m));
	return 0;
}

                
            
        
浙公网安备 33010602011771号