CF 687B Remainders Game(质因数分解&扩展中国剩余定理应用)

CF 687B Remainders Game(质因数分解&扩展中国剩余定理应用)

题目大意

现选定一个k与x,x未知,给出n个数c,可否根据x与c之间模数得出x模k?

解题思路

据扩展中国剩余定理,可以知道

我们总可以将两个同余式子
{ x a 1 ( m o d   m 1 ) x a 2 ( m o d   m 2 ) \begin{cases}x\equiv a_1 (mod\ m_1)\\x\equiv a_2(mod\ m_2)\end{cases}
转化为一个式子
x k 1 m 1 + a 1 ( m o d   l c m ( m 1 , m 2 ) ) x\equiv k_1m_1+a_1(mod\ lcm(m_1,m_2))
其中 k 1 k_1 为方程 k 1 m 1 k 2 m 2 = a 2 a 1 k_1m_1-k_2m_2=a_2-a_1 的一个解

而易证当 d m d\mid m 时,且 x   m o d   m x\ mod\ m 确定时 x   m o d   d x\ mod\ d 也就确定了

由此,我们只需求出所有的数之间的最小公倍数,观察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;
}	

猜你喜欢

转载自blog.csdn.net/baiyifeifei/article/details/88535933
今日推荐