前言
这样的函数 可以用线性筛,于是我就自己推了推,发现自己有好多问题没学透...
最后好不容易过了,但是常数巨大,实际上还不如 O(nlnn)...
题目
解法
Part 1
i 挺难搞的,但由于 gcd(n,i)=gcd(n,n−i),我们可以把 i 两两分组都凑成 n。
然后我试了试这个式子(这个式子到最后推不动,如果不想看的可以跳过):
具体就是 n 没有数进行配对,如果 n 是偶数那么 n2 也没有数配对,所以在后面再算。
然后想到枚举 gcd。
推到这里发现不能用欧拉函数搞,因为 (n−1)/2g 这个范围和 ng 不同。
发现了这个方法有问题的原因后,我们不妨换一种思路:将 igcd(i,n) 看成 ngcd(i,n),这样需要将答案除以 2,但是我们发现 i 的值域可以达到 n 了!
有一个小细节,12∑ni=1ngcd(i,n) 并没有算第 n 项,因为 ∑ni=1ngcd(i,n) 是个奇数,而那个 1 是第 n 项贡献的,所以在除二的时候被除掉了。最后我又加回去了。
在这个式子里,第 n 项就是 d=1 的情况,此时 φ(1)=0,所以也没有算第 n 项。
Part 2
然后我们发现 g(i)=i×φ(i) 肯定是个积性函数,只不过我们要求的是 f(n)=∑d|nd×φ(d)。此外我们还需要定义辅助函数 pk(i),假设 i 中最小质因子 p 在 i 中的幂次为 k,那么 pk(i)=pk。
-
i 为质数。f(i)=i(i−1),pk(i)=i。
-
i 与 p 互质。
考虑相对 i,ip 的因数增加了什么 —— 容易发现它们都是 p 的倍数。那么就有:
f(ip)=f(i)+∑kp|ipg(kp)k 和 p 一定是互质的,可以用反证法,就不赘述。于是就有:
f(ip)=f(i)+(f(i)+1)×g(p)pk(ip)=p加一是因为 f(i) 没有计算约数为 1 的情况,但这在 f(ip) 里对应着 p。我就被这个坑了很久。
-
i 与 p 不互质。
将 i 拆分成 j×pk。类似地,考虑增加的因数都是 pk+1 的倍数。于是有:
f(ip)=f(i)+(f(j)+1)×g(pk+1)pk(ip)=pk(i)×p加一的理由同上。
总结
除了单纯的积性函数之外,应该还可以用线性筛搞搞积性函数的 “前缀和”。
我倒戈了,暴力加它不香吗?
代码
#include <cstdio>
#define print(x,y) write(x),putchar(y)
template <class T> inline T read(const T sample) {
T x=0; int f=1; char s;
while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
return x*f;
}
template <class T> inline void write(const T x) {
if(x<0) return (void) (putchar('-'),write(-x));
if(x>9) write(x/10);
putchar(x%10^48);
}
const int maxn=1e6+5;
int n,p[maxn],pc;
long long f[maxn],pk[maxn];
bool is[maxn];
void init() {
f[1]=0;
for(int i=2;i<=maxn-5;++i) {
if(!is[i]) p[++pc]=i,f[i]=1ll*i*(i-1),pk[i]=i;
for(int j=1;j<=pc and i*p[j]<=maxn-5;++j) {
is[i*p[j]]=1;
if(i%p[j]==0) {
f[i*p[j]]=f[i]+(f[i/pk[i]]+1)*(pk[i]*p[j]-pk[i])*pk[i]*p[j];
pk[i*p[j]]=pk[i]*p[j];
break;
}
f[i*p[j]]=f[i]+(f[i]+1)*(p[j]-1)*p[j];
pk[i*p[j]]=p[j];
}
}
}
signed main() {
init();
for(int T=read(9);T;--T) {
int n=read(9);
print(f[n]*n/2+n,'\n');
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥