UVA - 11014 Make a Crystal (莫比乌斯反演)
给定一个n*n*n的立方体(中心点为原点O),选择尽量多的点,使得对于任意两点A,B,B不在线段OA上。
可以发现,原问题可转化为三维坐标下的点(x,y,z)中有多少个点的gcd(x,y,z)=1。
这道题我一开始想用欧拉函数做,但我发现需要求出1-n中与每个整数x互质的数的个数,于是试图修改一下欧拉函数的公式,结果发现计算出来的结果存在微小的偏差,原因是n不一定能被x的所有因子整除,使得(n/p)*(n/q)≠n/pq。被逼无奈,于是学了莫比乌斯反演。
莫比乌斯反演的做法是:令n=n/2,在1⩽的限制条件下,设f(X)为gcd(x,y,z)=X的点的个数,F(X)为gcd(x,y,z)=kX的点的个数,则F(X)=\sum\limits_{X|d}f(d),根据莫比乌斯反演定理则有f(X)=\sum \limits_{X|d}\mu (\frac{d}{X})F(d),f(1)即为x,y,z均大于0情况下的答案。由于又有F(X)=\left \lfloor \frac{n}{X} \right \rfloor^3,因此可以在O(n)的时间内算出f(X)。
然后用同样的方法可以算出x,y,z中有一个为0,另外两个大于0情况下的答案,将F(X)换为\left \lfloor \frac{n}{X} \right \rfloor^2即可。
一共有8个卦限,坐标平面上的12个象限,将结果乘一乘加一加,再加上在坐标轴上的6种情况,就得到答案了。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const ll N=1e5+10; 6 ll n,mu[N],d[N],c[N],ka; 7 void init() { 8 mu[1]=1; 9 for(ll i=1; i<N; ++i)if(mu[i]) 10 for(ll j=i*2; j<N; j+=i)mu[j]-=mu[i]; 11 } 12 ll F1(ll x) {return (n/x)*(n/x)*(n/x);} 13 ll F2(ll x) {return (n/x)*(n/x);} 14 ll f(ll x,ll F(ll)) { 15 ll ret=0; 16 for(ll i=x; i<=n; i+=x)ret+=F(i)*mu[i/x]; 17 return ret; 18 } 19 20 int main() { 21 init(); 22 while(scanf("%lld",&n)&&n) { 23 n/=2; 24 printf("Crystal %lld: %lld\n",++ka,f(1,F1)*8+f(1,F2)*12+6); 25 } 26 return 0; 27 }
还可以进一步优化,利用整除分块的方法,将复杂度降到O(\sqrt n)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const ll N=1e5+10; 6 ll n,mu[N],smu[N],ka,ans; 7 void init() { 8 mu[1]=1; 9 for(ll i=1; i<N; ++i)if(mu[i]) 10 for(ll j=i*2; j<N; j+=i)mu[j]-=mu[i]; 11 for(ll i=1; i<N; ++i)smu[i]=smu[i-1]+mu[i]; 12 } 13 14 int main() { 15 init(); 16 while(scanf("%lld",&n)&&n) { 17 n/=2; 18 ans=0; 19 for(ll l=1,r; l<=n; l=r+1) { 20 ll t=n/l; 21 r=n/t; 22 ans+=(t*t*t*8+t*t*12)*(smu[r]-smu[l-1]); 23 } 24 ans+=6; 25 printf("Crystal %lld: %lld\n",++ka,ans); 26 } 27 return 0; 28 }
以上筛莫比乌斯函数的方法复杂度是O(nlogn)的,也可以换成复杂度更低的O(n)的线性筛法,只是代码略长,不再赘述了。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 智能Agent如何改造传统工作流:从搜索到全能助手