考虑 DP。

状态

令 $f[\ell][x]$ 表示长度为 $\ell$,首项不超过 $x$ 的序列的个数。

答案是 $f[K][N]$。

有递推 $f[\ell][x] = f[\ell][x - 1] + f[\ell - 1][\floor{N/x}]$。照这个递推式求解,复杂度度太高;把它改成

$f[\ell][x] = \sum_{y = 1}^{x} f[\ell - 1][\floor{N/y}]$ 也就是枚举首项。

我们的目标是求出 $f[K][N]$,结合递推式来看,可以发现我们需要计算的状态的第二维都可以写成 $\floor{N/i}$。而我们熟知 $\floor{N/i}$ 的不同取值不超过 $2 \sqrt{N}$ 个。因此需要计算的状态不超过 $2K\sqrt{N}$ 个。

先来解决状态表示的问题,也就是 $\floor{N/i}$ 的表示问题。虽然 $\floor{N/i}$ 的取值不超过 $2\sqrt{N}$ 个,但是不能直接以 $\floor{N/i}$ 作为数组下标。可以这样做,对于 $\color{blue}{ i \le \sqrt{N} }$,用 $i$ 表示 $\floor{N/i}$,对于 $\color{red}{ i \ge \sqrt{N} }$,直接以 $\floor{N/i}$ 作为下标。从代码实现的角度说就是开两个数组,$f_1[1..K][1..\floor{\sqrt N}],\ f_2[1..K][1..\floor{\sqrt N}]$,$f_1[\ell][i] := f[\ell][i]$,$f_2[\ell][i] := f[\ell][\floor{N/i}]$。

注①:当 $N$ 是完全平方数时,$i \le \sqrt N$ 与 $i \ge \sqrt N$ 这两段中都含有 $\sqrt{N}$,这并不会造成问题。实际上分段时两侧都取等号是有意为之,这样可以使得递推式更简洁并且没有 corner case。这种分段方法适用于许多跟 $\floor{N/i}$ 相关的分块问题。

注②:关于上一段所说的“对于 $i \le \sqrt N$,用 $i$ 表示 $\floor{N/i}$”,我们不需要关心 $i \mapsto \floor{N/i}$ 是不是单射。这里所谓“表示 $\floor{N/i}$”是说设计一种方法来把所有需要计算的 $f[\ell][\floor{N/i}]$ 紧凑地存到数组里并且可以快速地由 $\ell, i$ 这两个 key 查到 $f[\ell][\floor{N/i}]$ 的值。不过可以证明,对于 $i \le \sqrt{N}$,$i \mapsto \floor{N/i}$ 确实是单射。

递推

对于 $f_1$,有递推

$f_1[l][x] = f_1[l][x - 1] + f[l - 1][\floor{N/x}]$

由于 $1 \le x \le \floor{\sqrt{N}}$,有 $f[l - 1][\floor{N/x}] = f_2[l-1][x]$,从而有

$f_1[l][x] = f_1[l][x - 1] + f_2[l-1][x]$

对于 $f_2$,有递推式

$f_2[l][i] = f_2[l][i+1] + \sum_{x=\floor{N/(i+1)} + 1}^{\floor{N/i}} f[l -1][\floor{N/x}] $

容易证明下列几个不等式

  1. $\floor{N/i} \ge \floor{N/(i + 1)}$
  2. $\floor{N/\floor{N/i}} \ge i$
  3. $\floor{N / \left(\floor{N/i} + 1 \right) } < i$

只证第 3 个。

设 $ \floor{\frac{N}{i}} = t$,我们有

$ t \le \frac{N}{i} < t + 1 \iff it \le N < i(t + 1) \iff i\frac{t}{t + 1} \le \frac{N}{t + 1} < i \implies \floor{\frac{N}{t + 1}} < i$

因此我们有 $i \le \floor{\frac{N}{x}} < i + 1$,即对于 $\floor{\frac{N}{i + 1}} < x \le \floor{\frac Ni}$ 恒有 $ \floor{\frac{N}{x}} = i $,这里我们得到一个很有用的等式

若 $\floor{\frac{N}{i}} \ge \floor{\frac{N}{i+1}}$,则

$f[l][\floor{\frac{N}{i}}] = f[l][\floor{N/(i + 1)}] + \left( \floor{\frac{N}{i}} - \floor{\frac{N}{i+1}} \right) f[l - 1][i] $

并且当 $\floor{\frac{N}{i}} > \floor{\frac{N}{i+1}}$ 时,$i$ 可表为 $\floor{ \frac{N}{ \floor{ \frac{N}{i} } } }$

从而有

\begin{aligned}

f_2[l][i] &= f_2[l][i+1] + \left( \floor{\frac{N}{i}} - \floor{\frac{N}{i+1}} \right) f[l - 1][i] \\

&= f_2[l][i+1] + \left( \floor{\frac{N}{i}} - \floor{\frac{N}{i+1}} \right) f_1[l - 1][i]

\end{aligned}

$f_2$ 的边界条件有两个:

1.

$f_2[1][i] = \floor{ \frac{N}{i} } $

2.

\begin{aligned} f_2[l][\floor{\sqrt{N}}] &:= f[l][\floor{\frac{N}{\floor{\sqrt N}}}] \\

&= f[l][\floor{\frac{N}{\floor{\sqrt N}+1}}] + \left( \floor{ \frac{N}{ \floor{\sqrt{N}} } } - \floor{ \frac{N}{\floor{\sqrt N}+1} } \right) f[l - 1][\floor{ \sqrt{N} } ] \\

&= f_1[l][\floor{\frac{N}{\floor{\sqrt N}+1}}] + \left(\floor{\frac{N}{\floor{\sqrt{N}}}} - \floor{\frac{N}{\floor{\sqrt{N}} + 1}} \right) f_1[l - 1][\floor{ \sqrt{N} } ]

\end{aligned}

代码

int main() {

    int n, k;
scan(n, k);
int r = sqrt(n + 0.5); // r is defined to be floor(sqrt{n})
vv<int> f1(k + 1, vi(r + 1)); // f1[len][i]:长为len,首项 <= i
vv<int> f2(k + 1, vi(r + 1)); // f2[len][i]:长为len,首项 <= n/i up (i, 1, r) {
f1[1][i]=i;
}
up (i, 1, r) {
f2[1][i] = n / i;
}
up (l, 2, k) {
up (i, 1, r) {
f1[l][i] = f1[l][i - 1] + f2[l - 1][i];
if (f1[l][i] >= mod) {
f1[l][i] -= mod;
}
}
f2[l][r] = f1[l][n/(r + 1)] + (ll)(n / r - (n / (r + 1))) * f1[l - 1][r] % mod;
if (f2[l][r] >= mod) {
f2[l][r] -= mod;
}
down (i, r - 1, 1) {
f2[l][i] = f2[l][i + 1] + (ll)(n / i - (n / (i + 1))) * f1[l - 1][i] % mod;
if (f2[l][i] >= mod) {
f2[l][i] -= mod;
}
}
}
println(f2[k][1]); return 0;
}

从另一个角度看待这个问题。以下所有 / 运算都向下取整。

取一个数字 m,求出 f[L][1..m]

f[L][i] = f[L][i-1] + f[L-1][N/i]

开一个数组 g[1..m],g[L][i] := f[L][N/i]

问题归结为如何计算 g[L][i]

上面已经得到

g[L][i] = g[L][i+1] + (L/i - L/(i+1))*f[L-1][i]

整个计算过程如下

for i = 1 to m

f[1][i] = i

g[1][i] = N/i

for L = 1 to K

f[L][0] = 0

for L = 2 to K

for i = 1 to m

f[L][i] = f[L][i-1] + g[L-1][i]

// compute g[L][m]

for i = m - 1 down to 1

g[L][i] = g[L][i+1] + (L/i - L/(i+1)) * f[L-1][i]

问题进一步归结为如何计算 g[L][m],即 f[L][N/m]

若 N/m <= m 则 f[L][N/m] 已经算出来了,不成问题。

若 N/m > m 但 N/(m + 1) <= m 则 f[L][N/m] = f[L][N/(m+1)] + (N/m - (N/(m+1))*f[L-1][m],也不成问题。

所以保险的办法是取 m 使得 N/(m + 1) <= m,取 m = floor(sqrt(N)) 就可以保证 N/(m+1) <= m。证明:m+1 > sqrt(N) 因此 N/(m+1) < sqrt(n) <= m 。

取 m = floor(sqrt(N)) + 1 可以保证 N / m < m。证明 m > sqrt(N),所以 N / m < sqrt(N) <= floor(sqrt(N)) < m。

ABC133F Small Products的更多相关文章

  1. Building third-party products of OpenCascade

    Building third-party products of OpenCascade eryar@163.com Available distributives of third-party pr ...

  2. SharePoint Configuration Wizard - Unable to upgrade SharePoint Products and Technologies because an upgrade is already in progress

    故障描述 当要运行SharePonit Products and Technologies Configuration Wizard的时候,出现了如下图所示的错误提示. 错误信息为: Unable t ...

  3. Registry values for ProductID and LocaleID for AutoCAD and the vertical products

    原文地址:http://adndevblog.typepad.com/autocad/2013/08/registry-values-for-productid-and-localeid-for-au ...

  4. magento添加多个产品到购物车(Add multiple products to cart )

    Step  1app\design\frontend\base\default\template\catalog\product\list.phtml<?php    $_productColl ...

  5. FVDI Commander products be replaced SVDI tools,really?

    You may have heard that some FVDI Commander products are being replaced by the new SVDI tools. This ...

  6. 读书笔记-《Training Products of Experts by Minimizing Contrastive Divergence》

    Training Products of Experts by Minimizing Contrastive Divergence(以下简称 PoE)是 DBN 和深度学习理论的 肇始之篇,最近在爬梳 ...

  7. /users/products.:format 这种写法的其对应解析字符写法

    “products.:format" 这种写法可以有对应的下面两种路由形式 /products.json /products.xml "products.:format?" ...

  8. Amazon.com: NEW VI AND VIM EDITOR KEYBOARD STICKER: Office Products

    Amazon.com: NEW VI AND VIM EDITOR KEYBOARD STICKER: Office Products NEW VI AND VIM EDITOR KEYBOARD S ...

  9. Popular Products

    Popular Products 描述 Given N lists of customer purchase, your task is to find the products that appea ...

随机推荐

  1. 「SNOI2017」礼物

    题目链接:Click here Solution: 设\(f(x)\)代表第\(x\)个人送的礼物的数量,\(s(x)\)代表\(f(x)\)的前缀和,即: \[ f(x)=s(x-1)+x^k\\ ...

  2. codevs 1464 装箱问题 2 x

                         题目描述 Description 一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1*1, 2*2, 3*3 ...

  3. Java当中的基本类型包装类

    Java当中的基本类型包装类 01 基本数据类型对象的包装类 **什么是基本数据类型对象包装类呢?**就是把基本数据类型封装成对象,这样就可以提供更多的操作基本数值的功能了. 基本数据类型对象的包装类 ...

  4. JVM-GC算法(二)-复制算法&&标记整理算法

    这次我和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一篇在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算法 ...

  5. python进程间的通信

    from multiprocessing import Queue, Process import time, random # 要写入的数据 list1 = ["java", & ...

  6. uniapp的微信小程序,获取授权,获取中文街道地理位置

    w问题描述:在微信小程序模拟器上运行获取坐标时 获取不到信息,原因是 没有调起默认地理位置: 解决办法:或者在manifest.json的源码视图中配置:配置appid和地理位置 默认弹起获取地理位置 ...

  7. pycharm2019连接mysql错误:08801 ------Connection to django1@localhost failed. [08001] Could not create connection to database server. Attempted reconnect 3 times. Giving up.

  8. CentOS 7下使用Apache2部署Django项目,解决文件名中含有中文报错的问题

    系统版本: CentOS 7.3Apache 2.4 Django 1.11 问题描述 Django项目涉及上传操作,上传文件名称含有中文,若使用runserver启动服务,没有问题!若将Django ...

  9. fMRI数据分析处理原理及方法————转自网络

    fMRI数据分析处理原理及方法 来源: 整理文件的时候翻到的,来源已经找不到了囧感觉写得还是不错,贴在这里保存. 近年来,血氧水平依赖性磁共振脑功能成像(Blood oxygenation level ...

  10. dpkg软件包管理

    要想得心应手管理Ubuntu软件包,就必须熟悉其中最重要的软件包管理程序dpkg工具是Ubuntu软件包管理工具的基础.使用dpkg工具可以实现软件包的安装.卸载.查询.编译.打包等功能. dpkg( ...