题意略。

思路:

将每一个点的坐标 (x,y,z) 与 (1,1,1) 相减,得到向量 (x - 1,y - 1,z - 1) 我们实际上就是要求出 这样互质的三元组有多少对就行了。

我们把这个长方体分成3部分:

1.三条坐标棱                                      2.在坐标棱上的三个表面(除去坐标棱)                                3.长宽高分别为[L - 1,W - 1,H - 1]的长方体

三条坐标棱我们只要开3枪,就可以贯穿这个部分,ans += 3。

至于2和3,我们可以用莫比乌斯的第二类反演来解决。

在用莫比乌斯反演时,如果我们一 一枚举因子,就会T,我们来考虑一个sqrt(n)的优化。

比如说19这个数:

19 / 1 = 19,19 / 2 = 9,19 / 3 = 6,19 / 4 = 4,19 / 5 = 3,19 / 6 = 3,19 / 7 = 2,19 / 8 = 2,19 / 9 = 2,19 /10 = 1,......,19 / 19 = 1

在进行反演时,我们必然是通过枚举分母,计算出F(i) = (L / i) * (W / i) * (H / i)。

然而可以发现,7,8,9只要枚举一个就行,10~19也只需要枚举一个就行,如果我们用sum[ i ] 来维护mu[ i ]的前缀和,

那么ans += mu[ 7 ] * 19 / 7 + mu[ 8 ] * 19 / 8 + mu[ 9 ] * 19 / 9   等价于  ans += (sum[ 9 ] - sum[ 6 ]) * 19 / 7。

我们知道对于任意一个数x >= a * b,它的这种小于它且可以产生不同b的a最多有2 * sqrt(x)个。

详见代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = ; LL l,w,h;
bool check[maxn];
LL prime[maxn];
LL mu[maxn],sum[maxn]; void mobius(){
memset(check,false,sizeof(check));
mu[] = ;
sum[] = ;
int tot = ;
for(LL i = ;i < maxn;++i){
if(!check[i]){
prime[tot++] = i;
mu[i] = -;
}
for(int j = ;j < tot;++j){
if(i * prime[j] > maxn) break;
check[i * prime[j]] = true;
if(i % prime[j] == ){
mu[i * prime[j]] = ;
break;
}
else mu[i * prime[j]] = -mu[i];
}
sum[i] = sum[i - ] + mu[i];
}
} int main(){
mobius();
while(scanf("%lld%lld%lld",&l,&w,&h) == ){
LL ans = ;
LL len = min(l,min(w,h)),last;
for(LL i = ;i < len;i = last + ){
LL a = (l - ) / i,b = (w - ) / i,c = (h - ) / i;
last = min((l - ) / a,min((w - ) / b,(h - ) / c));
ans += (sum[last] - sum[i - ]) * (a * b * c);
}
len = min(l,h);
for(LL i = ;i < len;i = last + ){
LL a = (l - ) / i,b = (h - ) / i;
last = min((l - ) / a,(h - ) / b);
ans += (sum[last] - sum[i - ]) * (a * b);
}
len = min(l,w);
for(LL i = ;i < len;i = last + ){
LL a = (l - ) / i,b = (w - ) / i;
last = min((l - ) / a,(w - ) / b);
ans += (sum[last] - sum[i - ]) * (a * b);
}
len = min(w,h);
for(LL i = ;i < len;i = last + ){
LL a = (w - ) / i,b = (h - ) / i;
last = min((w - ) / a,(h - ) / b);
ans += (sum[last] - sum[i - ]) * (a * b);
}
ans = ans + ;
printf("%lld\n",ans);
}
return ;
}

最新文章

  1. weui 图片弹框
  2. style设置/获取样式的问题 和 offsetWidth/offsetHeight的问题
  3. Java控制台中输入中文输出乱码的解决办法
  4. l来自wentao:项目加入缓存(redis),实时调试时用 -----可视化缓存,flushdb
  5. 程序员是怎么炼成的---OC题集--练习答案与题目(1)
  6. semat内核阿尔法的状态图
  7. linux之SQL语句简明教程---INSERT INTO
  8. Chrome设计文档-多进程架构
  9. spring源码
  10. PredictionIO+Universal Recommender快速开发部署推荐引擎的问题总结(1)
  11. LNMP 与 LAMP 架构的区别及配置解决方案
  12. LeetCode Javascript实现 344. Reverse String 292. Nim Game 371. Sum of Two Integers
  13. 执行Python出现LookupError: unknown encoding: cp65001解决办法
  14. eShopOnContainers 看微服务④:Catalog Service
  15. git命令详解( 九 )
  16. 【C编程基础】C程序常用函数
  17. ubuntu12.04 mysql 卸载安装
  18. [LeetCode&amp;Python] Problem 720. Longest Word in Dictionary
  19. 浅谈如何使用Netty开发高性能的RPC服务器
  20. C# 新特性

热门文章

  1. spark 源码分析之十九 -- DAG的生成和Stage的划分
  2. mysql查询表所有列名,并用逗号分隔
  3. 遇见Python集合类型
  4. 【经验分享】ASP.NET 的 Page_Load 执行了2次,真的!
  5. 对Rust所有权、借用及生命周期的理解
  6. java的properties文件从数据库添加到文件
  7. POI导入excel
  8. 第十章 Fisco Bcos 权限控制下的数据上链实操演练
  9. 1、大型项目的接口自动化实践记录--robotframework环境搭建
  10. 学习Qt的一点小感想