题解 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$~

posted @ 2021-01-25 18:28  ffffyc  阅读(16)  评论(0)    收藏  举报  来源