ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 Prime

2021-08-25 06:31:07  阅读:151  来源: 互联网

标签:Prime 筛到 题解 质数 long 枚举 根号 define


传送门

考场上魔改了一下线性筛,觉得要筛到 \(\frac{R}{2}\) 就没让它跑
其实正解就是这样,只不过由于接下来类似埃氏筛的过程只要筛到根号就行了

  • 线性筛有的时候其实并不需要筛到 \(\frac{n}{2}\),如果接下来需要枚举倍数,注意可能只需要枚举到根号就行了

发现 \(R\) 的范围很大,但 \(R-L\) 的范围有限
而 \(L\) 的范围只有 \(1e7\),可以筛出质数来,再用类似埃氏筛的方法筛掉 \([L, R]\) 内的类质数
然后枚举一遍统计个数就好了

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 10000010
#define ll long long 
#define reg register int
#define rll register long long 
//#define int long long 

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline ll read() {
	ll ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

ll l, r, k;
int pri[N], pcnt, ans;
bool npri[N];

namespace force{
	ll ans;
	void solve() {
		for (ll i=l; i<=r; ++i) {
			for (ll j=2; j<=min(i-1, k); ++j)
				if (!(i%j)) goto jump;
			//printf("%lld,%lld\n", i, (ans^=i));
			//printf("%lld ", i);
			ans^=i;
			jump: ;
		}
		//printf("\n");
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace task1{
	void solve() {
		for (reg i=2,limr=r,limk=k; i<=limr; ++i) {
			if (i<=limk && !npri[i]) pri[++pcnt]=i;
			for (reg j=1; j<=pcnt&&1ll*i*pri[j]<=r; ++j) {
				npri[i*pri[j]]=1;
				if (!(i%pri[j])) break;
			}
		}
		for (reg i=l,limr=r; i<=limr; ++i)
			if (!npri[i]) ans^=i; //, cout<<i<<' '; cout<<endl;
		printf("%d\n", ans);
		exit(0);
	}
}

namespace task2{
	void solve() {
		ll ans=0;
		for (rll i=l; i<=r; ++i) ans^=i;
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace task3{
	bool nspr[N];
	void solve() {
		for (reg i=2,lim=min((ll)(sqrt(r)),k); i<=lim; ++i) {
			if (!npri[i]) pri[++pcnt]=i;
			for (reg j=1; j<=pcnt&&1ll*i*pri[j]<=lim; ++j) {
				npri[i*pri[j]]=1;
				if (!(i%pri[j])) break;
			}
		}
		for (reg i=1; i<=pcnt; ++i) {
			//cout<<"i: "<<i<<' '<<pri[i]<<endl;
			for (rll j=max((l-1)/pri[i]+1,2ll),lim=r/pri[i]; j<=lim; ++j) {
				//cout<<j*pri[i]<<' '<<j*pri[i]-l<<endl;
				nspr[j*pri[i]-l]=1; //, cout<<j*pri[i]<<endl;
			}
		}
		ll ans=0;
		//for (int i=0; i<=100; ++i) cout<<nspr[i]<<' '; cout<<endl;
		for (reg i=0,lim=r-l+1; i<lim; ++i) if (!nspr[i]) ans^=(l+i);
		printf("%lld\n", ans);
		exit(0);
	}
}

signed main()
{
	l=read(); r=read(); k=read();
	//force::solve();
	if (k==1) task2::solve();
	else if (r<=1000) force::solve();
	else if (r<=(ll)(1e7)) task1::solve();
	else task3::solve();
	
	return 0;
}

标签:Prime,筛到,题解,质数,long,枚举,根号,define
来源: https://www.cnblogs.com/narration/p/15183275.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有