2022.9.24 闲话

呃呃为啥 午间闲话 之后闲话目录多了一个 downvote 啊 .

[这里我想放一个类似 Lag Train 的 PV 里面的哭泣脸,但是我没有啊 TAT,假装这里有一个吧]

在 artalter 帮助下修了一下 Abel 变换 XD


想更 知识落差限制想象力 但是发现能放的想法都比较 naive .

想写点知识点发现自己啥也不会 .

想写点杂题发现简单的不想写难的不会写 .


Wheel Factorization 属于数论高级科技中比较水的了,大体就是对朴素筛子(埃氏筛和欧拉筛)做了一些综合和优化 .

令素数序列为 {p},则取前 k 个素数的乘积 B=i=1kpi,则 nn+B 对于这 k 个素数的整除性是一样的,那么我们把值域按块长为 B 分块,这看起来就像用一个长 B 的轮子滚过数轴,所以说叫 Wheel Factorization .

为了保证复杂度我们应当取最大的 k 使得 Bn,根据素数定理可以得到 k=Θ(logn) .

Mertens' Theorem 指出 1BB 个数里有 O(Blogk) 个数不被钦定的 k 个素数整除,也就是说我们还有 O(nlogk) 也就是 O(nloglogn) 个数没被筛出来,这些数也就是所有最小素因数大于 pk 的数,我们跑一个欧拉筛筛出来就好了 .

时间复杂度 O(nloglogn) .

Code:

const int N = 55555555, BLK = 2*3*5*7*11*13*17, B = BLK + 8, M = 7, D = 1959;
int prime[N], mark[B];
bool notprime[B], pblock[B], cblock[B];
inline int wheel()
{
	memset(pblock, true, sizeof pblock); pblock[0] = false;
	int cc = 0, bcnt = 0, ans; notprime[0] = notprime[1] = true;
	for (int i=2; i<=BLK; i++)
	{
		if (!notprime[i]){prime[++cc] = i; if (cc <= M) pblock[i] = false;}
		for (int j=1; (j<=cc) && (i*prime[j] <= BLK); j++)
		{
			int now = i * prime[j]; notprime[now] = true;
			if (j <= M) pblock[now] = false;
			if (!(i % prime[j])) break;
		}
	}
	for (int i=1; i<BLK; i++)
		if (pblock[i]) mark[++bcnt] = i;
	ans = cc;
	for (int i=1; i<D; i++)
	{
		int L = i * BLK, R = (i + 1) * BLK - 1;
		memcpy(cblock, pblock, sizeof(bool) * BLK);
		for (int j=M+1; prime[j]*prime[j]<=R; j++)
		{
			int t1 = max((L-1) / prime[j] + 1, prime[j]) * prime[j], t2 = prime[j] << 1;
			if (!(t1 & 1)) t1 += prime[j];
			for (int k=t1-L; k<BLK; k+=t2) cblock[k] = false;
		}
		for (int j=1; j<=bcnt; j++)
			if (cblock[mark[j]]) prime[++ans] = L + mark[j];
	}
	return ans; // prime count
}

板子就是 SPOJ PRIMES2 .

posted @   yspm  阅读(64)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
😅​
点击右上角即可分享
微信分享提示