ZOJ3435
题意略。
思路:
将每一个点的坐标 (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 ;
}
ZOJ3435的更多相关文章
- [ZOJ3435]Ideal Puzzle Bobble
题面戳我 题意:你现在处于\((1,1,1)\),问可以看见多少个第一卦限的整点. 第一卦限:就是\((x,y,z)\)中\(x,y,z\)均为正 sol 首先L--,W--,H--,然后答案就变成了 ...
- zoj3435(莫比乌斯反演)
题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3435 题意: 给出一个三维坐标 (x, y, z), 问该点与 ...
随机推荐
- sql nvarchar类型和varchar类型存储中文字符长度
今天遇到了,随手记录一下. sql server 存储数据里面 NVARCHAR 记录中文的时候是 一个中文对应一个字符串长度,记录英文也是一个字母一个长度 标点符号也是一样. ...
- 原生 js基础常用的判断和循环
原生 js基础常用的判断和循环 以下部分是个人实践及和搜集的资料: 最常用的if判断语句: if (/* 条件表达式 */){ // 成立执行语句 } else { // 否则执行语句 } 原生js的 ...
- CMS简单内容管理系统
架构 NewsDaoSQLServerImpl public class NewsDaoSQLServerImpl extends BaseDao implements NewsDao { publi ...
- firewalld防火墙命令规则设置
1.firewalld的基本使用 启动/关闭: systemctl start/stop firewalld 查看状态: systemctl status firewalld 开机启用/禁用 : sy ...
- 记录一下我做Udacity 的Data Scientist Nano Degree Project
做项目的时候看了别人的blog,决定自己也随手记录下在做项目中遇到的好的小知识点. 最近在做Udacity的Data Scientist Nano Degree Project的Customer_Se ...
- 【Java例题】7.1 线程题1-时间显示线程
1.时间显示线程.设计一个示线程子类,每秒钟显示一次当前时间:然后编写主类,在主函数中定义一个线程对象,并启动这个线程 package chapter7; import java.text.Simpl ...
- 算法与数据结构基础 - 折半查找(Binary Search)
Binary Search基础 应用于已排序的数据查找其中特定值,是折半查找最常的应用场景.相比线性查找(Linear Search),其时间复杂度减少到O(lgn).算法基本框架如下: //704. ...
- PHP版本的区别与用法详解
在我们安装PHP模块时,有时需要注意PHP编译的版本,下面讲解下PHP中VC6.VC9.TS.NTS版本的区别与用法详解,介绍php的两种执行方式. 1. VC6与VC9的区别:VC6版本是使用Vis ...
- android ——活动
活动(Activity)主要用于和用户进行交互,是一种可以包含用户界面的组件. 1.手动创建活动 右击com.example.administrator.exp5→New→Activity→Empty ...
- 使用selenium进行爬取掘金前端小册的数据
Selenium 简介 百度百科介绍: Selenium [1] 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, ...