【题解】 [NOI Online #1 入门组]跑步 dp+根号分治+拆分数 Luogu6189

Legend

Link \(\textrm{to Luogu}\)

\(n\) 的拆分数。

\(1 \le n \le 10^5\)

Editorial

Simple \(O(n \sqrt{n})\)

考虑到一个事实:\(\le \sqrt{n}\) 的数字只有 \(O(\sqrt{n})\) 个,可以暴力完全背包。

完全背包显然没有人不会。复杂度 \(O(n \sqrt{n})\)

考虑到另一个事实:\(>\sqrt{n}\) 的数字最多只会被选 \(O(\sqrt{n})\) 个,可以暴力 \(dp\)

怎么 \(dp\)?设 \(dp_{i,j}\) 为把 \(j\) 拆分成 \(i\) 个数字的方案数,总状态数是 \(O(n \sqrt{n})\) 的。

转移有 \(dp_{i,j}=dp_{i-1,j-(\sqrt{n}+1)}+dp_{i,j-i}\) 两种。

含义分别为选择一个 \(\sqrt{n}+1\) 大小的物体和把所有物体高度增加 \(1\)。这样可以涵盖所有情况。

这一部分复杂度也是 \(O(n \sqrt{n})\)

再用 \(O(n)\) 合并两个背包的答案,总复杂度 \(O(n \sqrt{n})\)

$O(n \log n) $

一切的前提,模数要是 \(\rm{NTT}\) 模数。显然本题用不了这个做法

考虑毒瘤的生成函数做法:

拆分数的生成函数显然为 \(F(x)=\prod\limits_{i=1}^{\infty} \sum\limits_{j=0}^{\infty}(x^i)^j\)

根据 \(\sum_{i=0}^{\infty} x^i=\frac{1}{1-x}\) 可以得出 \(F(x)=\prod\limits_{i=1}^{\infty} \dfrac{1}{1-x^i}\)

两边同时取 \(\ln\)\(\ln F(x)= -\sum\limits_{i=1}^{\infty}\ln (1-x^i)\)

现在的问题就是如何计算 \(h(x)=\ln(1-x)\),因为 \(\ln F(x)= -\sum\limits_{i=1}^{\infty}h(x^i)\)

求个导数 \(h'(x)=-\frac{1}{1-x}=-\sum\limits_{i=0}^{\infty}x^i\)

同时积分有 \(h(x)= - \sum\limits_{i=1}^{\infty}\frac{x^i}{i}\),求完了。

带回 \(F(x)\)\(\ln F(x)= \sum\limits_{i=1}^{\infty}\sum\limits_{j=1}^{\infty}\frac{x^{ij}}{j}=\sum\limits_{t=1}^{\infty}x^t \sum\limits_{j|t}\frac{1}{j}\)

显然这个式子可以调和级数 \(O(n \log n)\) 预处理完。

再把式子 \(\exp\) 回去就做完了。复杂度就是 \(O(n \log n)\)

Code

采用的根号分治做法。

#include <bits/stdc++.h>

#define debug(...) fprintf(stderr ,__VA_ARGS__)

using namespace std;

int n ,p;

const int MX = 1e5 + 23;
const int SIZE = 320;
int dp[MX];
int f[SIZE][MX] ,dp2[MX];

int main(){
	cin >> n >> p;
	dp[0] = 1 % p;
	for(int i = 1 ; i <= min(n ,SIZE) ; ++i){
		for(int j = i ; j <= n ; ++j){
			dp[j] = (dp[j] + dp[j - i]) % p;
		}
	}

	dp2[0] = f[0][0] = 1 % p;
	for(int i = 1 ; i < SIZE ; ++i){
		for(int j = SIZE + 1 ; j <= n ; ++j){
			f[i][j] = (f[i - 1][j - (SIZE + 1)] + f[i][j - i]) % p;
			dp2[j] = (dp2[j] + f[i][j]) % p;
		}
	}

	int Ans = 0;
	for(int i = 0 ; i <= n ; ++i){
		Ans = (Ans + 1LL * dp[i] * dp2[n - i]) % p;
	}
	printf("%d\n" ,Ans);
	return 0;
}
posted @ 2020-10-07 00:29  Imakf  阅读(153)  评论(0编辑  收藏  举报