P5325 【模板】Min_25筛

传送门

要求求积性函数 f(x) 的前缀和,f(prim) 是一个关于prim的简单多项式,f(prim^k) 可以快速计算

求法:

Min25 筛分为两部分,第一部分处理素数的幂在 P5325 【模板】Min_25筛 的前缀和

即     P5325 【模板】Min_25筛

Min25 的核心思想就是考虑小于根号n的质数可以出去大于根号n的合数的贡献

因此我们可以利用这个性质避免计算大于根号n的数的幂

设 P5325 【模板】Min_25筛 为已经筛了 j 个倍数,<= i 的数的 k 次幂和

P5325 【模板】Min_25筛

P5325 【模板】Min_25筛 为前 i 个质数的 k 次幂和, P5325 【模板】Min_25筛

换句话说,f 的作用就是一个质数一个质数去脱合数的衣服,当考虑完小于根号n的质数后,所有合数也被扒完了

P5325 【模板】Min_25筛

考虑多加一个质数会多拔去多少合数的贡献,这些贡献就是

P5325 【模板】Min_25筛

但这样会把质数的贡献减去,所以我们要加上质数的贡献

这样以来我们已经可以处理一些问题了,比如说 <=n的质数个数(0次幂),质数和 (1次幂)

第二部分就是把合数的贡献用积性函数的性质加回去

P5325 【模板】Min_25筛 表示 2 -- i 所有 Min(x) >= prim(j) 的和

P5325 【模板】Min_25筛

递推分为两部分考虑,一是大于等于pi 的质数,一是合数

质数的贡献我们已经知道,现在考虑如何加上合数的贡献,自己枚举合数的最小质因子与次数

P5325 【模板】Min_25筛

于是有   P5325 【模板】Min_25筛

后面一坨是因为没有考虑一个质数的次方的贡献

 

一些细节

我们发现求 f 的时候,n 只需要用到所有 P5325 【模板】Min_25筛 的状态,而 P5325 【模板】Min_25筛 

于是我们可以直接整除分块预处理 n / i 的所有状态然后离散化

//Part 1
for(ll l = 1, r; l <= n; l = r + 1){
    ll v = n / l; r = n / v; 
	if(v <= S) id1[v] = ++m; else id2[n / v] = ++m;
	w[m] = v; ll x = v % Mod;
	f1[m] = (x * (x+1) / 2) % Mod - 1; 
	f2[m] = mul(mul(x, x+1), mul(mul(2, x)+1, inv6)) - 1;
}
for(int i = 1; i <= tot; i++){
	for(int j = 1; j <= m && prim[i] * prim[i] <= w[j]; j++){
		ll k = Id(w[j] / prim[i]);
		f1[j] = dec(f1[j], mul(prim[i], dec(f1[k], s1[i-1])));
		f2[j] = dec(f2[j], mul(mul(prim[i], prim[i]), dec(f2[k], s2[i-1])));
	}
} 
// Part 2
ll Solve(ll x, int p){
	ll k = Id(x), ans = dec(dec(f2[k], f1[k]), dec(s2[p-1], s1[p-1]));
	for(int i = p; i <= tot; i++){
		if(prim[i] * prim[i] > x) break;
		for(ll e = 1, l = prim[i]; l <= x; l *= prim[i], e++){
			ll v = l % Mod;
			if(l * prim[i] <= x) ans = add(ans, mul(f(v), Solve(x / l, i + 1)));
			if(e > 1) ans = add(ans, f(v));
		}
	} return ans;
}

 

上一篇:基于MST的立体匹配算法


下一篇:牛客练习赛48 B 小w的a=b问题