Project Euler 468
Project Euler 468
题目
Smooth divisors of binomial coefficients
An integer is called B-smooth if none of its prime factors is greater than \(B\).
Let \(S_B(n)\) be the largest \(B\)-smooth divisor of \(n\).
Examples:
\(\begin{aligned} &S_1(10)=1\\ &S_4(2100) = 12\\ &S_{17}(2496144) = 5712 \end{aligned}\)
Define \(\displaystyle F(n)=\sum_{B=1}^n \sum_{r=0}^n S_B\left(\binom n r\right)\). Here, \(\displaystyle \binom n r\) denotes the binomial coefficient.
Examples:
\(\begin{aligned} &F(11) = 3132\\ &F(1111) \bmod 1\,000\,000\,993 = 706036312\\ &F(111\,111) \bmod 1\,000\,000\,993 = 22156169 \end{aligned}\)
Find \(F(11\,111\,111) \bmod 1\,000\,000\,993\).
解决方案
令\(\displaystyle{T_n(k)=\sum_{B=1}^n S_B(k),}\)则交换求和次序立即得到\(\displaystyle{F(n)=\sum_{r=0}^n T_n\left(\binom nr\right).}\)因此核心变成:对每个二项式系数 \(k=\dbinom nr\),高效计算 \(T_n(k)\)。
对任意整数 \(k\),有标准分解\(\displaystyle{k=\prod_{p}p^{v_p(k)}.}\)注意到\(\displaystyle{S_B(k)=\prod_{p\le B}p^{v_p(k)}.}\)因此当 \(B\) 在相邻质数之间变化时,\(S_B(k)\) 不会变。
令 \(n\) 内的质数为\(2=p_1<p_2<\cdots<p_t\le n,\)并补上\(p_0=1, p_{t+1}=n+1.\)定义前缀乘积\(\displaystyle{P_i(k)=\prod_{j=1}^{i}p_j^{v_{p_j}(k)}, P_0(k)=1.}\)
那么当 \(B\in[p_i,p_{i+1}-1]\) 时,\(S_B(k)=P_i(k).\)于是\(\displaystyle{T_n(k)=\sum_{B=1}^n S_B(k)=\sum_{i=0}^{t}(p_{i+1}-p_i)P_i(k).}\)设权重\(w_i=p_{i+1}-p_i,\)则上式是一个“权重 \(\times\) 前缀积”的形式:\(\displaystyle{T_n(k)=\sum_{i=0}^{t}w_iP_i(k)}\)
对 \(k=1\),显然 \(P_i(1)=1\),故\(\displaystyle{T_n(1)=\sum_{i=0}^t w_i=n.}\)。
利用经典递推:\(\dbinom n{r+1}=\dbinom nr\cdot \dfrac{n-r}{r+1}.\)从 \(r=0\) 的 \(k=\dbinom n0=1\) 出发,每一步用分子 \(n-r\) 乘上、分母 \(r+1\) 除掉。
若当前 \(k\) 被乘上某个质数幂 \(p^e\),那么对所有 \(B\ge p\) 的 smooth 因子都会多出 \(p^e\),即对所有 \(i\) 满足 \(p_i\ge p\) 的前缀积都要乘上 \(p^e\),等价于进行更行:\(P_i(k)\leftarrow P_i(k)\cdot p^e, \forall i\ge I(p).\)其中\(I(p)\)表示质数的序号(\(I(2)=1,I(3)=2\))。
因此对表达式\(\displaystyle{T_n(k)=\sum_{i=0}^{t}w_i,P_i(k)}\) 来说,乘上 \(p^e\) 就是对所有 \(i\ge I(p)\) 的项整体乘 \(p^e\),即一次 后缀乘法更新。同理,除以 \(p^e\) 就是乘上 \((p^e)^{-1}\bmod M\)。
直接维护 \(P_i(k)\) 并做后缀乘法会很麻烦。关键是引入“乘法差分”:定义一列因子 \(g_i\) 满足\(\displaystyle{P_i=\prod_{j=0}^{i}g_j,g_0=1.}\)
当我们要让所有 \(P_i\)(\(i\ge s\))统一乘上一个因子 \(a\) 时,只需令\(g_s\leftarrow g_s\cdot a,\)因为对 \(i\ge s\) 的前缀积都会包含 \(g_s\),而对 \(i<s\) 的前缀积不包含它。
因此可以我们可以考虑用线段树一些信息,单点更新时沿路径回溯更新即可。
于是\(\displaystyle{T_n(k)=\sum_{i=0}^{t}w_i\prod_{j=0}^{i}g_j.}\)现在每次乘/除一个质数幂,只对应 对某个位置 \(g_s\) 的单点乘法更新。
我们需要支持两种操作:
- 单点乘法:\(g_s\leftarrow g_s\cdot a\)
- 查询:\(\displaystyle{\sum_{i=0}^{t}w_i\prod_{j=0}^{i}g_j.}\)
对任意区间 \([L,R]\) 定义结点信息为一对:\((p,s)\),其中\(\displaystyle{p=\prod_{i=L}^{R} g_i,s=\sum_{i=L}^{R} w_i\prod_{j=L}^{i} g_j.}\)若区间拆为左右子区间 \([L,M]\) 与 \([M+1,R]\),则:
- 乘积显然:\(p=p_L\cdot p_R.\)
- 对加权和,右边的前缀积要先乘上左区间整体乘积:\(s=s_L+p_L\cdot s_R.\)
可见,根结点的 \(s\) 就是所求的 \(T_n(k)\)。
由于\(\dbinom nr=\dbinom n{n-r},\)从而\(T_n\left(\binom nr\right)=T_n\left(\binom n{n-r}\right).\)
令 \(h=\left\lfloor \dfrac n2\right\rfloor\),则
- 若 \(n\) 为奇数:\(\displaystyle{F(n)=2\sum_{r=0}^{h}T_n\left(\binom nr\right).}\)
- 若 \(n\) 为偶数:\(\displaystyle{F(n)=2\sum_{r=0}^{h}T_n\left(\binom nr\right)-T_n\left(\binom nh\right)}.\)
所以只需遍历 \(r=0\sim h\)。
最终维护好\(T_n(\cdot)\)的值并相加即可。
代码
1 |
|