Codeforces Round #671 (Div. 2)E. Decryption(因数分解、构造)

E. Decryption(因数分解、构造)

link
题意:给定合数 n n n,把他们的因子分出来,自己排顺序放在一个环上。要求相邻的数字 g c d ≠ 1 gcd\ne1 gcd=1。可以进行另外的向两数插入 l c m lcm lcm的操作。要求输出最小的操作数的序列
思路:都已经开始合数了必然开素数或者因数分解。但是 n ≤ 1 0 9 n\le10^9 n109,应该不能线性筛上了。

  1. 考虑用 n \sqrt{n} n 筛出他的因子(不包括素数) f a c i fac_i faci,找出因子的同时判断是不是素数( f a c i \sqrt{fac_i} faci 判断),是的化存到 p i p_i pi.我对他们进行了去重,考虑到之后可能有素数的次数 ≠ 1 \ne1 =1
  2. 操作数最小只可能有两种情况: ( a ) (a) a合数由两个次数为1的素数组成,操作数1 ( b ) (b) b其他,操作数为0
  3. 构造:数轴上放去重之后的素数组 p n p_n pn,在两个 p i 与 p i + 1 ( i < s u m p ( 素 数 总 个 数 ) ) p_i与p_{i+1}(i<sump(素数总个数)) pipi+1(i<sump())之间先放上 f a c n fac_n facn中不等于 去 素 数 因 子 组 p i ∗ p i + 1 去素数因子组p_i*p_{i+1} pipi+1 包 含 p i 包含p_i pi的合数,然后放上 p i ∗ p i + 1 p_i*p_{i+1} pipi+1。在 p s u m p p_{sump} psump与n之间把余下的放上,记得去重
int n;
int p[maxn], fac[maxn];
map<int, int>vis, facp, pp;
int main() {
    
    
	int T;
	int sumfac, sump, minn, flag, anss, tt;
	cin >> T;
	//primes((int)(sqrt(1e9)));
	while (T--)
	{
    
    
		cin >> n;
		vis.clear();
		facp.clear();
		pp.clear();
		sumfac = 0; sump = 0;

		for (int i = 2; (LL)i*i <= (LL)n; i++) {
    
    
			if (n%i == 0) {
    
    
				/*fac[++sumfac] = i;
				if (n / i != i)fac[++sumfac] = n / i;*/
				flag = 0;
				minn = i;
				for (int j = 2; (LL)j*j <= (LL)minn; j++) {
    
    
					if (minn%j == 0) {
    
    
						flag = 1;
						break;
					}
				}
				if (!flag) {
    
     if(pp[minn]==0)p[++sump] = minn; pp[minn]++; }
				else {
    
     if (facp[minn] == 0)fac[++sumfac] = minn; facp[minn] = 1; }
				flag = 0;
				minn = n / i;
				for (int j = 2; (LL)j*j <= (LL)minn; j++) {
    
    
					if (minn%j == 0) {
    
    
						flag = 1;
						break;
					}
				}
				if (!flag) {
    
     if (pp[minn] == 0)p[++sump] = minn; pp[minn]++; }
				else {
    
     if (facp[minn] == 0)fac[++sumfac] = minn; facp[minn] = 1; }
			}
		}
		if (sump == 2 && sumfac == 0) {
    
    
			
			cout << p[1] << " " << p[2] << " " << n << endl;
			cout << 1 << endl;
			continue;
		}
		for (int i = 1; i < sump; i++) {
    
    
			if (vis[p[i]])continue;
			cout << p[i] << " ";
			vis[p[i]] = 1;
			//ans[++anss] = p[i];
			for (int j = 1; j <= sumfac; j++) {
    
    
				if (fac[j] % p[i] == 0 && fac[j] != p[i] * p[i + 1] && vis[fac[j]] == 0) {
    
     cout << fac[j] << " "; vis[fac[j]] = 1; }
			}
			if (vis[p[i] * p[i + 1]] == 0) {
    
     cout << p[i] * p[i + 1] << " "; vis[p[i] * p[i + 1]] = 1; }
			//ans[++anss] = p[i] * p[i + 1];
		}
		cout << p[sump] << " ";
		for (int i = 1; i <= sumfac; i++) {
    
    
			if (fac[i] % p[sump] == 0 && vis[fac[i]] == 0) {
    
     cout << fac[i] << " "; vis[fac[i]] = 1; }
		}
		cout << n << endl;
		cout << 0 << endl;
		//ans[++anss] = n;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44986601/article/details/108753330