2022.9.24 闲话

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

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

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


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

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

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


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

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

为了保证复杂度我们应当取最大的 \(k\) 使得 \(B\le \sqrt n\),根据素数定理可以得到 \(k=\Theta(\log n)\) .

Mertens' Theorem 指出 \(1\dots B\)\(B\) 个数里有 \(O\left(\dfrac{B}{\log k}\right)\) 个数不被钦定的 \(k\) 个素数整除,也就是说我们还有 \(O\left(\dfrac n{\log k}\right)\) 也就是 \(O\left(\dfrac n{\log\log n}\right)\) 个数没被筛出来,这些数也就是所有最小素因数大于 \(p_k\) 的数,我们跑一个欧拉筛筛出来就好了 .

时间复杂度 \(O\left(\dfrac n{\log \log n}\right)\) .

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 @ 2022-09-24 20:13  Jijidawang  阅读(56)  评论(2编辑  收藏  举报
😅​