【ybt金牌导航8-4-2】【luogu P2158】【POJ 3090】可见点数 / 仪仗队 / Visible Lattice Points

可见点数 / 仪仗队 / Visible Lattice Points

题目链接:ybt金牌导航8-4-2 / luogu P2158 / POJ 3090

题目大意

有一个网格,然后可以从 (0,0) 向其它整数点画一条线,但是中间不能经过其它整数点。

问你可以画多少条线。

思路

在这里插入图片描述
我们考虑根据这个图,看看能不能发现什么。

然后你会发现它有对称性,就是左下-右上的线段是对称轴,它两边线段的分布情况和个数都对称。
然后它这条线上也有一个符合的线。

那你可以只求一种一边的个数,然后乘二加一,就是答案。

然后你考虑一边的怎么弄。
那你想到,如果不满足的线,它是怎么样的。
可以想到,如果一个点 (x,y),有 gcd(x,y)1,那必然至少会有点 (x/gcd(x,y),y/gcd(x,y)) 在连向它的线段上,就不行了。

那就变成了要 gcd(x,y)=1
那你可以枚举 x,然后就变成了求 1x 中与 x 互质的个数。
那就是欧拉函数了,这题要算很多个,可以用线性筛来做。

代码(ybt & luogu)

Tips

这里它网格的大小是 n(0,0)(n1,n1)
一定要注意不是到 (n,n),它是小于而不是小于等于。

#include<cstdio> #define ll long long using namespace std; int n, phi[40001], pr[40001]; bool np[40001]; ll ans; int main() { scanf("%d", &n); phi[1] = 1;//求出 1~n 每个数的 phi 值 for (int i = 2; i < n; i++) { if (!np[i]) { phi[i] = i - 1; pr[++pr[0]] = i; } for (int j = 1; j <= pr[0] && pr[j] * i < n; j++) { np[i * pr[j]] = 1; if (i % pr[j] == 0) phi[i * pr[j]] = phi[i] * pr[j];//不止一个这样的因子,只有第一个要减一 else phi[i * pr[j]] = phi[i] * (pr[j] - 1); if (i % pr[j] == 0) break;//第一次出现,要减一 } } for (int i = 1; i < n; i++)//对称性,乘二 ans += 2ll * phi[i]; ans++;//中间的那一条 printf("%lld", ans); return 0; }

代码(POJ)

Tips

这道题有多组数据,而且是 (0,0)(n,n)

我们可以把 φ 函数先预处理出来,然后再预处理乘二之后的前缀和,然后你就可以 O(1) 处理询问了。

//由于思路相同,代码实现也差不多,就不再作注释了 #include<cstdio> #define ll long long using namespace std; ll T, n, pr[40001]; bool np[40001]; ll phi[40001]; int main() { phi[1] = 1; for (ll i = 2; i <= 40000; i++) { if (!np[i]) { phi[i] = i - 1; pr[++pr[0]] = i; } for (ll j = 1; j <= pr[0] && pr[j] * i < 40000; j++) { np[i * pr[j]] = 1; if (i % pr[j] == 0) phi[i * pr[j]] = phi[i] * pr[j]; else phi[i * pr[j]] = phi[i] * (pr[j] - 1ll); if (i % pr[j] == 0) break; } } for (ll i = 1; i <= 40000; i++) phi[i] = phi[i - 1] + phi[i] * 2ll; scanf("%lld", &T); for (ll i = 1; i <= T; i++) { scanf("%lld", &n); printf("%lld %lld %lld\n", i, n, phi[n] + 1); } return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/YBT_JPDH_8-4-2.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(50)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示