Good Bye 2022: 2023 is NEAR

C. Koxia and Number Theory

cf链接

g c d ( a [ i ] + x , a [ j ] + x ) = = 1 gcd(a[i] + x, a[j] + x) = = 1 gcd(a[i]+x,a[j]+x)==1
辗转相减法
g c d ( a [ i ] + x , a [ j ] + x ) = g c d ( a b s ( a [ i ] − a [ j ] ) , a [ j ] + x ) gcd(a[i] + x, a[j] + x) = gcd(abs(a[i]-a[j]), a[j]+x) gcd(a[i]+x,a[j]+x)=gcd(abs(a[i]a[j]),a[j]+x)
也就是说如果最大公约数不等于一,那么肯定是 a b s ( a [ i ] − a [ j ] ) 的因子 也就是说如果最大公约数不等于一,那么肯定是abs(a[i] - a[j])的因子 也就是说如果最大公约数不等于一,那么肯定是abs(a[i]a[j])的因子
假设因子为p
( a [ j ] + x ) 的因子中不能有 p ,也就是 ( a [ j ] + x ) m o d p = = 0 (a[j] + x)的因子中不能有p,也就是(a[j] + x)modp == 0 (a[j]+x)的因子中不能有p,也就是(a[j]+x)modp==0
x ! = − a [ j ] m o d p 即 x ! = ( p − a [ j ] m o d p ) m o d p x != -a[j]modp 即 x!= (p -a[j]modp)modp x!=a[j]modpx!=(pa[j]modp)modp
如果 x ! = 0 , 1 , 2 , 3 , . . . , p − 1 的话就说明无解,不存在 x 使 g c d = 1 如果x!= 0,1,2,3,...,p-1的话就说明无解,不存在x使gcd=1 如果x!=0,1,2,3,...,p1的话就说明无解,不存在x使gcd=1
所以我们可以记录每个 p 上 x 不能等于数的个数,大于等于 p 就说明无解 所以我们可以记录每个p上x不能等于数的个数,大于等于p就说明无解 所以我们可以记录每个px不能等于数的个数,大于等于p就说明无解
只需要前一百的因子就够了
因为 n 小于 100 ,所以最多只会有 100 个不同的 a [ j ] 所以插入的数量也小于 100 ,所以只需要小于 100 的因子就够了,大于一百的也肯定不满足,因为数量不够 因为n小于100,所以最多只会有100个不同的a[j]所以插入的数量也小于100,所以只需要小于100的因子就够了,大于一百的也肯定不满足,因为数量不够 因为n小于100,所以最多只会有100个不同的a[j]所以插入的数量也小于100,所以只需要小于100的因子就够了,大于一百的也肯定不满足,因为数量不够


代码

#include
#include
#include
#include
#include

const int N = 1e5 + 10;

typedef long long ll;

using namespace std;

int pri[N];
bool vis[N];

ll arr[N];

int t, n;

int cnt;

void init_prime()
{
	for(int i = 2; i < 110; i ++)
	{
			if(!vis[i])
			{
				pri[cnt++] = i;
			}
			for(int j = 0; j < cnt; j ++)
			{
				if(pri[j] * i > 110) break;
				vis[pri[j]*i] = true;
				if(i % pri[j] == 0) break;	
			}
		
	}	
}

int main()
{
	unordered_map<int, set<int>> num;
	unordered_map<ll,int> sam;
	init_prime();
	cin >> t;
	while(t--)
	{
		
		bool f = 0;
		num.clear();
		sam.clear();
		cin >> n;
	
		for(int i = 0; i < n; i ++)
		{
			cin >> arr[i];
			sam[arr[i]] ++;
			if(sam[arr[i]] >= 2)
			{
				f = 1;	
			}
		}
	
		for(int i = 0; i < n; i ++)
		{
			for(int j = i+1; j < n; j ++)
			{
				ll t = abs(arr[i] - arr[j]);
				for(int k = 0; k < cnt; k ++)
				{
					if(t % pri[k] == 0)
					{
						ll tem = pri[k];
						num[tem].insert((tem - arr[j]%tem)%tem);
						if(num[tem].size() == tem)
						{
							f = 1; 
							break;
						}
					}
				}	
			}
		}
	
			if(f) puts("NO");
			else puts("YES");
	
	}
	return 0;
}

你可能感兴趣的:(CF思维题,算法,c++,数据结构)