GMOJ5516. Function

题目大意

i=1nd|iμ(d)σ02(id)

n109,T10

解题思路

讲题的时候讲的可能不太清晰。这里给出一个详细的过程。

许多人都发现了这道题是一个min_25筛的版题并爆切了,但是否有人尝试证明了呢?

根据SDOI2015 约数个数和,我们得到 σ0(ij)=x|iy|i[gcd(x,y)=1]

受此启发,加上式子中有 μ 函数,我们可以考虑反推出反演过程,即(从下往上看):

i=1nσ0(i2)=i=1nx|iy|i[gcd(x,y)=1]=i=1nx|iy|id|gcd(x,y)μ(d)=i=1nd|iμ(d)d|x,x|id|y,y|i1=i=1nd|iμ(d)σ02(id)

显然 f(x)=d(x2) 是一个积性函数,并且有f(pc)=2c+1,这与大家打表出来的结果一致。

最后本人猜测出题人也是这么想到的。

代码

#include <cmath>
#include <cstdio>
#include <algorithm>
#define fo(i, a, b) for(int i = (a); i <= (b); ++i)
#define ll long long
using namespace std;
const int N = 32e4;
bool v[N + 10];
int tot;
ll p[N + 10], n, sq, m, w[N + 10], sum[N + 10], g[N + 10], id1[N + 10], id2[N + 10];
void pre() {
	fo(i, 2, N)  {
		if(!v[i]) ++tot, p[tot] = i;
		for(int j = 1; p[j] * i <= N && j <= tot; ++j) {
			v[i * p[j]] = 1;
			if(!(i % p[j])) break;
		}
	}
	fo(i, 1, tot)	sum[i] = i * 3;
}
ll getid(ll x) { return x <= sq ? id1[x] : id2[n / x];}
ll S(ll x, int j) {
	if(p[j] > x) return 0;
	ll Ans = g[getid(x)] - sum[j];
	for(int i = j + 1; i <= tot && p[i] * p[i] <= x; ++i)
		for(ll e = 1, sp = p[i]; sp <= x; sp *= p[i], ++e)
			Ans += (e * 2 + 1) * (S(x / sp, i) + (e > 1));
	return Ans;
}
int main() {
	freopen("function.in", "r", stdin);
	freopen("function.out", "w", stdout);
	pre();
	int T;
	for(scanf("%d", &T); T; --T) {
		scanf("%lld", &n), sq = sqrt(n), m = 0;
		for(ll l = 1, r; l <= n; l = r + 1) {
			r = (n / (n / l)), w[++m] = n / l;
			g[m] = 3 * (w[m] - 1);
			w[m] <= sq ? id1[w[m]] = m : id2[n / w[m]] = m;
		}
		fo(i, 1, tot)
			for(int j = 1; j <= m && p[i] * p[i] <= w[j]; ++j)
				g[j] -= (g[getid(w[j] / p[i])] - sum[i - 1]);
		printf("%lld\n", S(n, 0) + 1);
	}
	return 0;
}
posted @   Martin_MHT  阅读(34)  评论(2编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示