分析
化简题意,可以看作为
问能否求出 \(x \bmod k\) 的值。
由于题目中并没有给定 \(m_1,m_2,m_3,\cdots,m_n\) 是否互质,运用中国剩余定理是无法解决的。
对于仅有两个同余方程的方程组:
我们可以把它化为这样的形式:
移项,得:
这就是一个典型的二元一次不定方程。根据裴蜀定理,有:
- 若 \(\gcd(m_1,m_2) \mid (p_2-p_1)\) 则原方程有解。
- 否则,原方程无解。
假设原方程有解,即 \(\gcd(m_1,m_2)\mid (p_2,p_1)\),设 \(d=\gcd(m_1,m_2)\)。
则 \((3)\) 式等价于 $$m_1k_1 \equiv p_2-p_1 \pmod {m_2} \tag{4}$$
等价于 $$\frac{m_1k_1}{d} \equiv \frac{p_2-p_1}{d} \pmod{\frac{m_2}{d}} \tag{5}$$
解得 $$k_1 \equiv (\frac{m_1}{d})^{-1}\times \frac{p_2-p_1}{d}\pmod{\frac{m_2}{d}} \tag{6}$$
即 $$k_1=k\frac{m_2}{d} + (\frac{m_1}{d})^{-1}\times \frac{p_2-p_1}{d} \tag{7}$$
将 \((7)\) 式代入 \((1)\) 式中,可得 $$x = k\frac{m_1m_2}{d} +m_1(\frac{m_1}{d})^{-1}\times \frac{p_2-p_1}{d} + p_1 \tag{8}$$
\((8)\) 式又等价于 $$x \equiv m_1(\frac{m_1}{d})^{-1}\times \frac{p_2-p_1}{d} + p_1 \pmod{\frac{m_1m_2}{d}}\tag{9}$$
令 \((\frac{m_1}{d})^{-1}\times \frac{p_2-p_1}{d} = b\),因为 \(\operatorname{lcm}(m_1,m_2)=\frac{m_1m_2}{\gcd(m_1,m_2)}\),所以 \((9)\) 式等于 $$x \equiv m_1b + p_1\pmod{\operatorname{lcm}(m_1,m_2)} \tag{10}$$
自此,我们证明了:若 \((1)\) 式有解,那么它在模 \(\operatorname{lcm}(m_1,m_2)\) 下有唯一解。
进而,对于有任意多个的,模数不互质的同余方程组,若它有解,那么它在模 \(\operatorname{lcm}(m_1,m_2,\cdots,m_n)\) 的意义下也有唯一解。
推导方法很简单,提取出前两个式子化成 \((10)\) 式的样子,放回去,根据 \(\operatorname{lcm}(\operatorname{lcm}(m_1,m_2),m_3) = \operatorname{lcm}(m_1,m_2,m_3)\) 一个个推就得到令最终的答案。
思路类似 P4777 扩展中国剩余定理,大家看完可以去做做。
代码
#include<bits/stdc++.h>
#define int long longnamespace IO {#define int long long #define gh getcharinline int read(){char ch=gh();int x=0;bool t=0;while(ch<'0'||ch>'9') t|=ch=='-',ch=gh();while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();return t?-x:x;}inline char getc(){char ch=gh();while(ch<'a'||ch>'z') ch=gh();return ch;}inline void write(int x){if(x < 0){putchar('-');x = -x;}if(x > 9){write(x / 10);}putchar((x % 10 + '0'));}
}
using namespace IO;
using namespace std;
const int Maxn = 100010;
int c[Maxn];
int gcd(int a,int b){if(a%b == 0)return b;return gcd(b,a%b);
}
signed main(){int n = read(), k = read();for(int i = 1; i <= n; i++)c[i] = read();int lcm = 1;for(int i = 1; i <= n; i++){lcm = lcm * c[i] / gcd(lcm,c[i]);lcm %= k;}if(lcm == 0)return puts("Yes");return puts("No");
}