CF1176D Recover it!

CF1176D Recover it!

题目描述

作者猜测了一个由 \(n\) 个整数构成的数组 \(a\),其中每个整数都不小于 \(2\) 且不大于 \(2 \cdot 10^5\)。你并不知道数组 \(a\),但你知道通过以下操作得到的数组 \(b\):

  1. 首先,让数组 \(b\) 等于数组 \(a\);
  2. 然后,对于每个 \(i\) 从 \(1\) 到 \(n\):
    • 如果 \(a_i\) 是质数,则将一个整数 \(p_{a_i}\) 添加到数组 \(b\),其中 \(p\) 是质数的无限序列(\(2, 3, 5, \dots\));
    • 否则(如果 \(a_i\) 不是质数),将 \(a_i\) 的最大真因子(不等于 \(a_i\) 的最大因子)添加到 \(b\);
  3. 最后,将得到的长度为 \(2n\) 的数组随机打乱顺序,并作为输入给你。

这里 \(p_{a_i}\) 表示第 \(a_i\) 个质数。第一个质数 \(p_1 = 2\),第二个质数是 \(p_2 = 3\),以此类推。

你的任务是还原出任意一个可以生成给定数组 \(b\) 的数组 \(a\)。保证一定存在解(即数组 \(b\) 是由某个合法的数组 \(a\) 生成的)。如果有多组解,你可以输出任意一组。

输入格式

第一行包含一个整数 \(n\)(\(1 \le n \le 2 \cdot 10^5\)),表示数组 \(a\) 的元素个数。

第二行包含 \(2n\) 个整数 \(b_1, b_2, \dots, b_{2n}\)(\(2 \le b_i \le 2750131\)),其中 \(b_i\) 是数组 \(b\) 的第 \(i\) 个元素。\(2750131\) 是第 \(199999\) 个质数。

输出格式

输出一行 \(n\) 个整数 \(a_1, a_2, \dots, a_n\)(\(2 \le a_i \le 2 \cdot 10^5\)),表示可以生成给定数组 \(b\) 的数组 \(a\),顺序任意。如果有多组解,你可以输出任意一组。

输入输出样例 #1

输入 #1

3
3 5 2 3 2 4

输出 #1

3 4 2 

输入输出样例 #2

输入 #2

1
2750131 199999

输出 #2

199999 

输入输出样例 #3

输入 #3

1
3 6

输出 #3

6 

说明/提示

由 ChatGPT 4.1 翻译

算法分析

首先预处理出\(2750131\)以内的质数,用线性筛,因为后面要用到一个数组。然后,对输入的数排序,也可以用桶存,只要从大到小遍历就行。如果\(a_i\)是质数,那么它一定是被生成的那一个,因为如果是原数,那么之前一定会有一个比它要大的质数带掉它,所以它是被生成的数。如果\(a_i\)是合数,那么他一定是原数组其中一个,因为如果被生成,那么之前一定会有一个比它要小的合数带掉它,所以它是原数组之一。最后对于每一组,输出对应的数就行了。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2750131;
int n;
int k = 0;
int cnt[maxn+5];
int a[400005];
int pos[maxn+5];
int p[maxn+5];
int vis[maxn+5];
void xxs(){//线性筛
	for(int i = 2; i<=maxn; i++){
		if(vis[i]==0){
			vis[i] = i;
			p[++k] = i;
			pos[i] = k;//对应是第几个质数
		}
		for(int j = 1; j<=k; j++){
			if(p[j]>vis[i] || i*p[j]>maxn){
				break;
			}
			vis[i*p[j]] = p[j];
		}
	}
}
int main(){
	xxs();
	cin>>n;
	for(int i = 1; i<=2*n; i++){
		int x;
		cin>>x;
		cnt[x]++;//桶
	}
	for(int i = maxn; i>=2; i--){
		while(cnt[i]>0){//还有剩
			if(pos[i]!=0){//是质数
				int a = pos[i];//对应编号
				cnt[i]--;
				cnt[a]--;
				cout<<a<<" ";
			}else{
				int t = i/vis[i];//最大因子
				cnt[i]--;
				cnt[t]--;
				cout<<i<<" ";
			}
		}
	}
	return 0;
}

总结

这道题代码好些,思路好想,所以可以评到黄,感觉评不到绿。

posted @ 2026-09-26 23:02  xmgene  阅读(2)  评论(0)    收藏  举报