[算进] BZOJ 2818(欧拉函数)
Problem
Solution
一眼莫反,许多年前好像用莫反做过。但是在其他大佬的博客里Get到了一种用欧拉函数的快速算法,写一下。
定理
\sum_{i=1}^n \sum_{j=1}^n [gcd(i,j)=1] = (\sum_{i=1}^n 2*φ(i)) - 1
很好理解。减去的 1 是多算的一个 (1,1)。
让后就可以切爆这题了。
Code
Talk is cheap.Show me the code.
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
int x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
return x * f;
}
const int N = 1e7+7;
int n,tot,ans;
int phi[N],p[N],sum[N];
bool vis[N];
void MakePhi() {
phi[1] = 1;
for(int i=2;i<=n;++i) {
if(!vis[i]) {
p[++tot] = i; phi[i] = i-1;
}
for(int j=1;j<=tot&&i*p[j]<N;++j) {
if(i%p[j] == 0) {
vis[i*p[j]] = 1, phi[i*p[j]] = phi[i]*p[j]; break;
} else vis[i*p[j]] = 1, phi[i*p[j]] = phi[i] * phi[p[j]];
}
}
for(int i=1;i<=n;++i)
sum[i] = sum[i-1] + phi[i];
}
signed main()
{
n = read();
MakePhi();
for(int i=1;i<=tot&&p[i]<=n;++i) {
ans += 2 * sum[n/p[i]] - 1;
}
printf("%lld\n",ans);
return 0;
}
Summary
这个定理很重要!!!
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具