题解 P3868 【[TJOI2009]猜数字】
P3868 [TJOI2009]猜数字
传送门
$\texttt{CRT}$ 的题怎么能不来乱搞呢?
这种写法很简单,思维难度也不高,也不需要用到快速乘。
思路
我们可以将题目中的要求转化为一个线性同余方程组:$$\begin{cases}n\equiv a_1(\mod b_1)\\n\equiv a_2(\mod b_2)\\n\equiv a_3(\mod b_3)\\...\\n\equiv a_k(\mod b_k)\end{cases}$$ 注意这里的 $a_i$ 要先对 $b_i$ 取模.
由于 $b_i$ 两两互质,我们显然地可以使用 $\texttt{CRT}$,但是不想写怎么办?
于是我们来乱搞。
我们依次处理每个同余条件,设现在处理到第 $i$ 个条件,最小的满足前 $i$ 条条件是数为 $s$.
显然,当 $i=1$ 时,$s=a_1$.
现在考虑推进至 $i=2$,如果 $s$ 已经与 $a_2$ 在模 $b_2$ 意义下同余,就不操作,继续跳到 $i=3$;否则,我们需要更新 $s$ 以满足条件 $2$,此时我们仍然要满足条件 $1$,于是我们就只能将 $s$ 加上 $b_1$ 的整数倍以满足条件 $2$.
同理当 $i=3$ 且 $s$ 不满足条件 $3$ 时,只能加上一个数 $l\equiv a_1(\mod b_1)$ 且 $l\equiv a_2(\mod b_2)$ 的整数倍.
所以,当处理第 $i$ 个条件时,$s$ 所能加上的只能是 $\texttt{lcm}(b_1,b_2,b_3,...,b_{i-1})$。因为 $\gcd(b_1,b_2,b_3,...,b_{i-1})=1$,所以 $\texttt{lcm}(b_1,b_2,b_3,...,b_{i-1})=\prod\limits_{j=1}^{i-1}b_j$.
由于满足条件时加数的次数不清楚(其实是我不会证),时间复杂度为 $O\texttt{(玄学能过)}$ .
接下来给出代码。
$Code:$
#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{
//read()
}using namespace IO;
ll a[11],b[11];
int main(){
int n=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<=n;i++){
b[i]=read();
a[i]=(a[i]%b[i]+b[i])%b[i];
}
ll sum=b[1],ans=a[1];
for(int i=2;i<=n;i++){
for(;ans%b[i]!=a[i];ans+=sum);
sum*=b[i];
}
printf("%lld",ans);
}
不过这种做法只能解决 $b$ 数组互质的情况,$b$ 数组不互质就只能安心写 $\texttt{EXCRT}$ 了。
再见了 $qwq$~

浙公网安备 33010602011771号