Project Euler 465
Project Euler 465
题目
Polar polygons
The kernel of a polygon is defined by the set of points from which the entire polygon’s boundary is visible. We define a polar polygon as a polygon for which the origin is strictly contained inside its kernel.
For this problem, a polygon can have collinear consecutive vertices. However, a polygon still cannot have self-intersection and cannot have zero area.
For example, only the first of the following is a polar polygon (the kernels of the second, third, and fourth do not strictly contain the origin, and the fifth does not have a kernel at all):

Notice that the first polygon has three consecutive collinear vertices.
Let \(P(n)\) be the number of polar polygons such that the vertices \((x, y)\) have integer coordinates whose absolute values are not greater than \(n\).
Note that polygons should be counted as different if they have different set of edges, even if they enclose the same area. For example, the polygon with vertices \([(0,0),(0,3),(1,1),(3,0)]\) is distinct from the polygon with vertices \([(0,0),(0,3),(1,1),(3,0),(1,0)]\).
For example, \(P(1) = 131, P(2) = 1648531, P(3) = 1099461296175\) and \(P(343) \bmod 1000000007 = 937293740\).
Find \(P(7^{13}) \bmod 1000000007\).
解决方案
设点集来自方格\(\mathcal G_n=\{(x,y)\in\mathbb Z^2:|x|\le n,|y|\le n\}\setminus\{(0,0)\}.\)把任意候选多边形的顶点按极角升序连接。原点严格在核心内可等价转化为两个条件:
- 同一条过原点射线上至多取一个点。否则远点会被近点在同方向遮挡,边界不可能从原点全部可见。
- 所选方向不被任何过原点的闭半平面完全包含。等价说法是:按极角排序后,相邻方向夹角都严格小于 \(\pi\)。
在这两个条件下,按极角连接得到的就是一个无自交、面积非零且原点在核心内的极多边形;反过来极多边形也必满足这两个条件。因此问题变成:在每条方向射线上选 0 或 1 个点,并且选出的方向集合不落在任何闭半平面内。
把方向按互质向量 \((a,b)\)(\(\gcd(|a|,|b|)=1\))分类。若该方向满足 \(\max(|a|,|b|)=d\),则该方向上可选点数\(c(d)=\left\lfloor \dfrac n d\right\rfloor .\) 并且满足 \(\max(|a|,|b|)=d\) 的方向数是\(8\varphi(d).\)
定义\(\displaystyle A=\prod_{u\in\mathcal U}(c_u+1),N=\sum_{u\in\mathcal U}c_u,Q=\sum_{u\in\mathcal U}c_u^2.\)其中 \(\mathcal U\) 表示全部方向的索引集合。则有 \(\displaystyle A=\prod_{d=1}^n\left(\left\lfloor\frac nd\right\rfloor+1\right)^{8\varphi(d)}=M^8,\)其中\(\displaystyle M=\prod_{d=1}^n\left(\left\lfloor\frac nd\right\rfloor+1\right)^{\varphi(d)}.\)
同时可得\(\displaystyle N=(2n+1)^2-1=4n(n+1),Q=\sum_{d=1}^n 8\varphi(d)\left\lfloor\frac nd\right\rfloor^2=8S,S=\sum_{d=1}^n\varphi(d)\left\lfloor\frac nd\right\rfloor^2.\)
先数每个方向至多选一个点的非空集合,可得数量为\(A-1\)。接着减去落在某个闭半平面内的坏集合。用锚点计数:选一个具体点 \(P\) 作为半平面边界上的锚点(共 \(N\) 种);其余点只能从与 \(P\) 对应的闭半平面内各方向选或不选,这一乘积恒为 \(\sqrt A\)(这是因为对向方向成对、半圈取一侧)。所以锚点计数总数是 \(N\sqrt A\)。
但坏集合中,含一对关于原点对向点的集合会被双计一次。双计总数为\(\dfrac Q2\)(每对对向方向贡献 \(c_u c_{-u}=c_u^2\),再除以 \(2\) 去重)。于是\(P(n)=(A-1)-\left(N\sqrt A-\dfrac Q2\right)= A-N\sqrt A+\dfrac Q2-1.\)代入 \(A=M^8,\sqrt A=M^4,N=4n(n+1),Q=8S\),得到
\[ P(n)=M^8-4n(n+1)M^4+4S-1. \]
记欧拉函数前缀和为\(\displaystyle\Phi(x)=\sum_{k=1}^x\varphi(k).\)那么我们考虑使用数论分块来计算。我们按 \(\left\lfloor \dfrac n l\right\rfloor\) 分块:若\(q=\left\lfloor\dfrac nl\right\rfloor,r=\left\lfloor\dfrac n q\right\rfloor,\)则在区间 \([l,r]\) 上商都等于 \(q\),且权重\(\displaystyle \sum_{k=l}^r\varphi(k)=\Phi(r)-\Phi(l-1).\)于是
\[ M=\prod_{b} (q+1)^{\Phi(r)-\Phi(l-1)}, S=\sum_{b} q^2\bigl(\Phi(r)-\Phi(l-1)\bigr). \]
块数是 \(O(\sqrt n)\)。
利用欧拉函数的和恒等函数的Dirichlet 卷积:\(\displaystyle\sum_{d=1}^m \varphi(d)\left\lfloor\frac md\right\rfloor=\frac{m(m+1)}2,\)可得递推\(\displaystyle\Phi(m)=\frac{m(m+1)}2-\sum_{l=2}^m \Phi\left(\left\lfloor\frac ml\right\rfloor\right).\) 对相同商分组(\(l\to r=\lfloor m/(m/l)\rfloor\))可在 \(O(\sqrt m)\) 时间求一个 \(\Phi(m)\)。
代码
1 |
|