「Luogu P4884」多少个1?

给定和模数,保证为质数,求最小的使得$111\cdots 1$(个)

链接

Luogu P4884

题解

注意到(个),则

然后这个方程就化为的标准形式了,由于模数为质数,直接利用即可。
由于会很大,所以再次建议不要用自己写的哈希表,而使用我是不会告诉你我因为这个原因被洛谷的数据坑了好几次了

代码

为了保险,这里开了,美中不足的是要自己写读写,顺便写了一个的龟速乘。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include<bits/stdc++.h>
using namespace std;
typedef __int128 ll;
map<ll,ll>ht;
ll mod,val;
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline void write(ll num)
{
if(num>9)
{
write(num/10);
}
putchar(num%10+'0');
}
inline ll qmul(ll x,ll y,ll mod)
{
ll l=(y>>25)*x%mod*((1<<25)%mod),r=(y&((1<<25)-1))*x%mod;
return (l+r)%mod;
}
inline ll qpow(ll base,ll exponent,ll mod)
{
if(!exponent)
{
return 1;
}
ll temp=qpow(base,exponent>>1,mod);
ll res=qmul(temp,temp,mod);
if(exponent&1)
{
res=qmul(res,base,mod);
}
return res;
}
inline ll BSGS(ll base,ll res,ll mod)
{
ht.clear(),res%=mod;
ll temp,val,fail;
temp=sqrt((long double)(mod))+1;
for(register int i=0;i<temp;i++)
{
val=qmul(res,qpow(base,i,mod),mod);
ht[val]=i;
}
base=qpow(base,temp,mod);
if(!base)
{
return !res?1:-1;
}
for(register int i=0;i<=temp;i++)
{
val=qpow(base,i,mod),fail=ht.find(val)==ht.end()?-1:ht[val];
if(fail>=0&&i*temp-fail>=0)
{
return i*temp-fail;
}
}
return -1;
}
int main()
{
val=read(),mod=read();
val=(qmul(9,val,mod)+1)%mod;
write(BSGS(10,val,mod));
}