线性筛筛一般积性函数

线性筛筛一般积性函数

前置芝士

线性筛、积性函数

有用的结论

\(f(x)\)\(g(x)\) 都是积性函数,则 \(h(x) = f(x) \cdot g(x)\) 也是积性函数
\(f(x)\)\(g(x)\) 都是积性函数,则 \(h(x \cdot y)=\sum\limits_{x\cdot y=n}f(x) \cdot g(y)\) 也是积性函数

How to do

给定一个积性函数 \(f(x)\)
要求能快速计算 \(f(p)\)\(f(p^{k})\) 其中 \(p\) 为质数
对于每个数 \(x\),记录它最小的质因子的幂 记为 \(low[n]\) 比如 \(low[60]=2^{2}=4\)
\(x\) 的最小质因子 \(p\) 指数为一,那么直接套用公式 \(f(x)=f(\frac{x}{p}) \cdot f(p)\)
否则分两类讨论:
\(x=p^{k}\) 根据 \(f(p^{k-1})\) 计算 \(f(p^k)\)
否则把 \(x\) 分解成 \(\frac{x}{low[x]}\)\(low[x]\) 再使用上面公式计算

example1:

\(f(n)=\sum\limits_{d|n} d \cdot \varphi(d)\)

f[1] = 1;
for (int i = 2; i <= n; i++)
{
	if (low[i] == 0)
	{
		low[i] = i, prime.emplace_back(i);
		f[i] = 1ll * (i - 1) * i + 1ll;
	}
	for (auto j : prime)
	{
		if (i * j > n)
			break;
		if (i % j == 0)
		{
			low[i * j] = low[i] * j;
			if (low[i] == i)
			{
				f[i * j] = f[i] + 1ll * (i * j - i) * (i * j);
			}
			else
			{
				f[i * j] = f[i / low[i]] * f[low[i] * j];
			}
			break;
		}
		low[i * j] = j;
		f[i * j] = f[i] * f[j];
	}
}

lazytag

posted @ 2025-07-28 17:46  floaya  阅读(18)  评论(1)    收藏  举报