【Codeforces】Educational Codeforces Round 89 (Div. 2) D. Two Divisors | 质因数分解

161 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情

【Codeforces】Educational Codeforces Round 89 (Div. 2) D. Two Divisors | 质因数分解

题目链接

Problem - 1366D - Codeforces

题目

image.png

题目大意

给定 nn 个正整数 a1,a2,...,ana_1,a_2,...,a_n,对于每个 1in1\le i\le n,找到一对正整数 di,1d_{i,1}di,2d_{i,2} 满足以下条件:

  1. di,1aid_{i,1}\mid a_i
  2. di,2aid_{i,2}\mid a_i
  3. gcd(di,1+di,2,ai)=1gcd(d_{i,1}+d_{i,2},a_i)=1

如果不存在符合条件的正整数 di,1d_{i,1}di,2d_{i,2},就对应输出 -1

思路

每个对 aia_i 的查询相互独立,我们只考虑如下问题:
对于给定的正整数 aa,求出两个正整数 xxyy 满足:

  1. xax\mid a
  2. yay\mid a
  3. gcd(x+y,a)=1gcd(x+y,a)=1

我们先对 aa 进行质因数分解,使得

a=i=1kpieia=\prod_{i=1}^k p_i^{e_i}

其中 kkaa 不同质因数的数量,pip_i 是质数且对任意 1u,vk,uv1\le u,v\le k,u\neq v 均满足 pupvp_u\neq p_v

此时,若 k1k\le 1 则无解。 否则一组合法的 (x,y)(x,y)

{x=p1e1y=i=2kpiei\begin{cases} x=p_1^{e_1}\\ y=\prod_{i=2}^k p_i^{e_i} \end{cases}

理由如下:
对于 aa 的任意一个质因数 pip_i
如果 pixp_i\mid x,那么一定有 piyp_i\nmid y
如果 piyp_i\mid y,那么一定有 pixp_i\nmid x
所以一定有 pi(x+y)p_i\nmid (x+y)
aax+yx+y 没有公共的质因数。

我们直接 O(a)O(\sqrt{a})aa 进行质因数分解会 TLE,需要先预处理出 107\sqrt{10^7} 范围内的质数加速质因数分解。

代码

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <math.h>
#include <map>
#include <queue>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
using LL=long long;
const int N=1e6+5;
//const LL mod=998244353;
const LL mod=1e9+7;
int p[N],v[N],tot,n=3171;
int a,x[N],y[N];
LL solve()
{
	scanf("%d",&n);
	for (int i=1;i<=n;++i)
	{
		scanf("%d",&a);
		for (int j=1;p[j]*p[j]<=a;++j)
			if (a%p[j]==0)
			{
				x[i]=1;
				while (a%p[j]==0) a/=p[j],x[i]*=p[j];
				break;
			}
		if (a==1||x[i]==0)
		{
			x[i]=y[i]=-1;
			continue;
		}
		y[i]=a;
	}
	
	for (int i=1;i<=n;++i) printf("%d ",x[i]);
	printf("\n");
	for (int i=1;i<=n;++i) printf("%d ",y[i]);
	return 0;
}
int main()
{
	for (int i=2;i<=n;++i)
	{
		if (!v[i]) p[++tot]=i;
		for (int j=1;j<=tot&&i*p[j]<=n;++j)
		{
			v[i*p[j]]=1;
			if (i%p[j]==0) break;
		}
	}
	int T=1;
	while (T--) solve();
	return 0;
}