携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
题目描述
阿宁有一个长度为 n 的正整数数组 a,她有很多次询问,每次询问:在数组 a 的前 x 个数中,未出现的最小质数是多少?
输入描述:
第一行输入两个正整数 n,q 表示数组的长度和询问的次数。
第二行输入 n 个正整数 ai,表示数组的每一个元素。
接下来 q 行,每行一个正整数 x,代表一次询问。
1≤n,q≤2×10^5
1≤ai≤10^9
1≤x≤n
输出描述:
输出 q 行,表示每次询问的答案。
示例1
输入
5 5
8 2 3 6 5
1
2
3
4
5
输出
2
3
5
5
7
说明
8 不是质数,未出现的最小质数是 2。
在 8,2 中,质数有 2,未出现的最小质数是 3。
在 8,2,3 中,质数有 2,3,未出现的最小质数是 5。
在 8,2,3,6 中,质数有 2,3,未出现的最小质数是 5。
在 8,2,3,6,5 中,质数有 2,3,5,未出现的最小质数是 7。
问题解析
既然题目要求输出前x个数内没出现的质数,那么我们可以先从2开始算出一定量的质数,然后再从数组的前x个数里开始比较,看那些质数没有出现过。
算出多少质数合适呢?数组的最大长度是2e5,所以极端情况下我们至少要处理出2e5+1个质数,即数组的数全都是质数。而大概2到3e6之间就有这么多的质数。那么我们可以先用质数筛筛出2到3e6之间所有的质数。然后在处理每次询问。
但如果对于每次询问,我们都重新计算一遍结果,显然是不行的。所以我们应该对于x=(1,2,……,n)先预处理所有的结果,把结果都存入数组f中,那么对于每个询问,答案就是:f[x]。
(具体看代码)
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
//#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 1e7 + 50, MOD = 1e11 + 3;
//p数组存放的是质数,cnt是质数个数
int p[N], cnt;
//st[i]表示第i个数是否是质数
bool st[N];
//质数筛
void get_primes()
{
int n =3e6;
for (int i = 2; i <= n; i++)
{
if (!st[i])p[cnt++] = i;
for (int j = 0; p[j] <= n / i; j++)
{
st[i * p[j]] = true;
if (i % p[j] == 0)break;
}
}
}
void solve()
{
get_primes();
int n, q;
cin >> n >> q;
vector<int>v(n+1), f(n+1);
for (int i = 1; i <= n; i++)
{
cin >> v[i];
}
//p数组的下标,p[l]就是目前没出现过的最小质数
int l = 0;
//记录数出现的次数
unordered_map<int, int>mymap;
for (int i = 1; i <= n; i++)
{
mymap[v[i]] = 1;
//如果这个质数出现过了,下标++
while (mymap[p[l]] == 1)
l++;
//记录答案
f[i] = p[l];
}
while (q--)
{
int x;
cin >> x;
cout << f[x] << endl;
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}