CF 687B Remainders Game(质因数分解&扩展中国剩余定理应用)
题目大意
现选定一个k与x,x未知,给出n个数c,可否根据x与c之间模数得出x模k?
解题思路
据扩展中国剩余定理,可以知道
我们总可以将两个同余式子
转化为一个式子
其中
为方程
的一个解
而易证当 时,且 确定时 也就确定了
由此,我们只需求出所有的数之间的最小公倍数,观察k是否为这些数中任一的因数即可
AC代码
#include<bits/stdc++.h>
using namespace std;
const int sz=1e6+5;
bool prime[sz];
int min_prime[sz];
void init()
{
for(int i=2;i<sz;i++) prime[i]=true;
for(int i=2;i<sz;i+=2)
{
prime[i]=false;
min_prime[i]=2;
}
prime[2]=true;
for(int i=3;i*i<sz;i+=2)
{
if(prime[i])
{
for(int j=i*i;j<sz;j+=2*i)
if(prime[j])
prime[j]=false,
min_prime[j]=i;
}
}
for(int i=2;i<sz;i++) if(prime[i]) min_prime[i]=i;
}
int cnt[sz];
bool check(int k)
{
while(k>1)
{
int temp=min_prime[k];
do{
k/=temp;
if(--cnt[temp]<0) return false;
}while(min_prime[k]==temp);
}
return true;
}
int main()
{
init();
memset(cnt,0,sizeof(cnt));
int n,k;
scanf("%d%d",&n,&k);
int x;
while(n--)
{
scanf("%d",&x);
while(x>1)
{
int temp=min_prime[x];
int tt=0;
do{
x/=temp;
tt++;
}while(min_prime[x]==temp);
cnt[temp]=max(cnt[temp],tt);
}
}
if(check(k)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}