[NOIP2021] 报数 题解

[NOIP2021] 报数 题解


知识点

埃氏筛,离线。

分析

首先暴力很简单,直接枚举强行判断即可。

接下来考虑优化,发现 \(1 \le x \le 10^7\),那么完全是可以预处理出来的。

模仿埃氏筛,会得到一个常数极小的筛法,时间复杂度大概 \(O(X\log_{2}{\log_{2}{X}})\)

(你想欧拉筛也可以试试,但是 std::bitsetstd::vector 配合埃氏筛是实际效率最高的。)

然后我们可以直接二分来查询答案,但是有超时的风险,所以离线后尺取即可。

代码

时间复杂度:\(O(X\log_2{\log_2{X}} + T)\),空间复杂度:\(O(\frac{X}{w}+T)\),其中 \(w=32\)

#define Plus_Cat "number"
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define Fi first
#define Se second
#define ll long long
#define Pii pair<int,int>
#define RCL(a,b,c,d) memset(a,b,sizeof(c)*(d))
#define FOR(i,a,b) for(int i(a);i<=(int)(b);++i)
#define DOR(i,a,b) for(int i(a);i>=(int)(b);--i)
#define tomin(a,...) ((a)=min({(a),__VA_ARGS__}))
#define tomax(a,...) ((a)=max({(a),__VA_ARGS__}))
#define EDGE(g,i,x,y) for(int i(g.h[x]),y(g[i].v);~i;y=g[i=g[i].nxt].v)
using namespace std;
constexpr int N(1e7+10),Qr(2e5+10);

bitset<N> f;
bool p(int x) {
	for(; x; x/=10)if(x%10==7)return 1;
	return 0;
}
void Init(int n=N-5) {
	FOR(i,7,n)if(!f[i]) {
		if(i%7==0) {
			f[i]=1;
			continue;
		}
		if(p(i))for(int j(i); j<=n; j+=i)f[j]=1;
	}
}

int Q;
namespace Subtask_Online {
	bool Check() {
		return Q<=100;
	}
	void Query() {
		FOR(i,1,Q) {
			int x;
			scanf("%d",&x);
			if(f[x])puts("-1");
			else {
				do ++x;
				while(f[x]);
				printf("%d\n",x);
			}
		}
	}
	int Cmain() {
		Init();
		Query();
		return 0;
	}
}

namespace Subtask_All {
	int tot;
	int ans[Qr];
	Pii qr[Qr];
	void Scan() {
		FOR(i,1,Q) {
			int x;
			scanf("%d",&x);
			if(f[x])ans[i]=-1;
			else qr[++tot]=Pii(x,i);
		}
		sort(qr+1,qr+tot+1);
	}

	void Solve(int n=N-5) {
		int it(1);
		FOR(i,1,n)if(!f[i]) {
			while(it<=tot&&qr[it].Fi<i)ans[qr[it].Se]=i,++it;
			if(it>tot)break;
		}
	}

	void Print() {
		FOR(i,1,Q)printf("%d\n",ans[i]);
	}

	int Cmain() {
		Init();
		Scan();
		Solve();
		Print();
		return 0;
	}
}

int main() {
#ifdef Plus_Cat
	freopen(Plus_Cat ".in","r",stdin),freopen(Plus_Cat ".out","w",stdout);
#endif
	scanf("%d",&Q);
	if(Subtask_Online::Check())return Subtask_Online::Cmain();
	return Subtask_All::Cmain();
}

posted @ 2024-11-13 13:50  Add_Catalyst  阅读(44)  评论(0)    收藏  举报