题解 P4861 【按钮】
LeavingZzz · · 题解
Solution For P4861
Upd: 更新了代码部分,使其符合日报讲解
厚颜无耻宣传博客的同余方程笔记
题意简述
一个数字
分析
不要被所谓的
的最小整数解
题目没有保证
证明
看做一个不定方程 ,只有
所以
证毕
那么套
(超小声
设
对于同余方程
即
预处理分母,然后当模
分母怎么预处理呢?
因为我们的解形式是
预处理出
暴力枚举
若存在那么最小解就是
\mathsf{Code:}
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
struct Hash_Table{ //手写的哈希表比map快很多
static const LL MOD=233333;
LL Hash[MOD+7],V[MOD+7],stk[MOD+7],top;
Hash_Table() {memset(Hash,-1,sizeof(Hash));top=0;}
inline void clear() {while(top) Hash[stk[top--]]=-1;return ;}
inline void insert(LL val,LL mi)
{
LL h=val%MOD;
while(Hash[h]!=-1&&Hash[h]!=val) ++h;
Hash[h]=val;V[h]=mi;
stk[++top]=h;
return ;
}
inline LL find(LL val)
{
LL h=val%MOD;
while(Hash[h]!=-1&&Hash[h]!=val) ++h;
return Hash[h]==val?V[h]:-1;
}
}H;
LL A,C;
inline LL gcd(LL a,LL b)
{
return a%b==0?b:gcd(b,a%b);
}
inline LL fast_pow(LL b,LL k,LL m)
{
LL s=1;
while(k)
{
if(k&1) s=s*b%m;
b=b*b%m;
k>>=1;
}
return s;
}
inline LL BSGS()
{
LL sqrtm=ceil(sqrt(C)),ti=1;
for(int i=0;i<sqrtm;i++)//预处理出A^j
{
H.insert(ti,i);
ti=ti*A%C;
}
LL t=ti=fast_pow(A,sqrtm,C),ans;
for(int i=1;i<=sqrtm;i++)
{
if((ans=H.find(ti))!=-1)
return i*sqrtm-ans;
ti=ti*t%C;
}
}
int main()
{
scanf("%lld%lld",&C,&A);
if(gcd(A,C)!=1)//无解
printf("Let's go Blue Jays!");
else printf("%lld",BSGS());
return 0;
}
蟹蟹管理大大审核^_^