博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[2018.4.2集训]b-容斥-计数
阅读量:5309 次
发布时间:2019-06-14

本文共 1016 字,大约阅读时间需要 3 分钟。

题目大意

有一个长宽均为 N 的网格, 每个格子的长宽均为 1. 除了最左下角的网

格外, 其他格子中均有一个半径为 $\frac{R}{10^6}$ 的圆, 圆心在格子的正中心. 现在你站
在最左下角的格子的正中心, 求你能够看到多少个圆, 视线不能够穿过圆.

$n \leq 10^9,1 \leq R \leq 5*10^5$

题解

加强版的仪仗队......

首先,显然坐标不互质的一定看不到。

其次,对于一个圆,如果它遮住了某个圆的一半以上,那么沿被它遮住的圆与观察点构成的直线对称处一定有另一个圆恰好遮住了被遮住的圆的对称的另一半。
因此,一个圆不被遮住的条件是圆心不被遮住。

考虑点到直线的距离公式,假设被挡住的圆是$(x,y)$,挡它的圆是$(a,b)$,那么有$\frac{(ay-bx)^2}{x^2+y^2} \geq r^2$。

此处有一个性质:若$x,y$互质,那么一定存在$a,b$,满足$a < x,b < y,|ay-bx|=1$。可以发现,此时一定是最近的。

于是只需要$x^2+y^2 < \frac{1}{r^2}$即可不被挡住。

于是,可以爆枚$x,y$的约数$d$,并暴力数出合法的$(x,y)$数目,容斥一下即可。

代码:

#include
using namespace std;typedef long long ll;const int N=1e6+9;int n,r;inline int read(){ int x=0;char ch=getchar(); while(ch<'0' || '9'
r && y>0)y--; ret+=y; } return ret;}int main(){ n=read();r=read(); init(); ll ans=(n==1?0:2);n--; ll lim=999999999999ll/r/r; for(ll d=1;d*d<=lim;d++) ans+=mu[d]*calc(lim/d/d,n/d); printf("%lld\n",ans); return 0;}

转载于:https://www.cnblogs.com/zltttt/p/8711710.html

你可能感兴趣的文章
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
Python-S9-Day127-Scrapy爬虫框架2
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
右侧导航栏(动态添加数据到list)
查看>>
81、iOS本地推送与远程推送详解
查看>>
虚拟DOM
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
关于View控件中的Context选择
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
Spark的启动进程详解
查看>>
使用命令创建数据库和表
查看>>
机器视觉:SSD Single Shot MultiBox Detector
查看>>
201521123044 《Java程序设计》第1周学习总结
查看>>
MIT Scheme 的基本使用
查看>>
程序员的“机械同感”
查看>>
在16aspx.com上下了一个简单商品房销售系统源码,怎么修改它的默认登录名和密码...
查看>>
c++回调函数
查看>>
linux下Rtree的安装
查看>>
【Java】 剑指offer(53-2) 0到n-1中缺失的数字
查看>>