首页 > 其他分享 >[NOI Online #1 入门组] 跑步 题解

[NOI Online #1 入门组] 跑步 题解

时间:2022-10-24 19:55:51浏览次数:56  
标签:ch NOI int 题解 复杂度 circ Online 做法

[NOI Online #1 入门组] 跑步 题解

一个经典问题:计数将正整数\(n\)拆分为若干个正整数的方案数,这里拆成的正整数是无序的,对\(P\)取模。

容易得到\(O(n^2)\)解法

设\(f_{i,j}\)表示用\(j\)个数得到\(i\)的方案数。转移即考虑增加一个数为\(1\)或全部数加\(1\)。

或者设\(f_{i,j}\)表示用\(\le j\)的数得到\(i\)的方案数。转移即考虑选不选\(j\)。

然而似乎无法继续优化。

下面就是本题的关键了。画出\(\text{Ferrers}\)图,如图

\[\begin{matrix} &\circ &\circ &\circ &\circ &\circ &\circ\\ &\circ &\circ &\circ &\circ\\ &\circ &\circ &\circ\\ &\circ &\circ\\ &\circ &\circ\\ &\circ \end{matrix} \]

这里将一行看成一个数。

考虑上面的\(O(n^2)\)做法在\(\text{Ferrers}\)图上的实质。

第一种做法是每次在下方加一个点或在左方加一列。复杂度为\(O(n \times 行数)\)。

第二种做法是每次加一行或者将当前可加行长度加一。复杂度为\(O(n \times 列数)\)。

我们想要将行数和列数同时控制在一个合适的范围内,这样把两个做法拼起来或许就能优化。

于是考虑强制第一种做法中每加一个点就加\(B\)个,第二种做法中至多将当前可加行长度累加至\(B - 1\)

这样第一种做法中行数至多为\(\frac{n}{B}\)复杂度就是\(O(\frac{n^2}{B} + nB)\)

取\(B = \sqrt{n}\),可得最优复杂度为\(O(n\sqrt{n})\)

点我看代码 |ू・ω・` )
#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;
template <typename T>
inline void read(T &x) {
	x = 0; int f = 0; char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
	for(; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
	if(f) x = ~x + 1;
}
const int B = 317;
const int N = 1e5 + 10;
int n, P, m, ans;
int f[N][B + 10], g[N][B + 10];
LL sg[N];
inline void update(int &x, int y) {if((x += y) >= P) x -= P;}
int main() {
	read(n), read(P);
	for(int i = 0; i <= B; ++i) f[0][i] = 1;
	for(int i = 1; i <= n; ++i) {
		for(int j = 1; j < B; ++j) {
			f[i][j] = f[i][j - 1];
			if(i >= j) update(f[i][j], f[i - j][j]);
		}
	}
	m = n / B + 1;
	sg[0] = g[0][0] = 1;
	for(int i = 1; i <= n; ++i) {
		for(int j = 1; j <= m; ++j) {
			if(i >= B) update(g[i][j], g[i - B][j - 1]);
			if(i >= j) update(g[i][j], g[i - j][j]);
			sg[i] += g[i][j];
		}
		sg[i] %= P;
	}
	for(int i = 0; i <= n; ++i) 
		update(ans, f[i][B - 1] * sg[n - i] % P);
	printf("%d\n",ans);
}

标签:ch,NOI,int,题解,复杂度,circ,Online,做法
From: https://www.cnblogs.com/DCH233/p/16822587.html

相关文章

  • Codeforces Round #401 (Div. 2) 题解 (待续)
    AShellGame#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#define#define......
  • April Fools Contest 2017 题解
    ANumbersJokeJoke数列,OEIS#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define......
  • Codeforces Round #402 (Div. 1) 题解(待续)
    AStringGame#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#define#defin......
  • BZOJ 1189([HNOI2007]紧急疏散evacuate-网络流二分+拆点)
    发生了火警,所有人员需要紧急疏散!假设每个房间是一个NM的矩形区域。每个格子如果是’.’,那么表示这是一块空地;如果是’X’,那么表示这是一面墙,如果是’D’,那么表示这是一扇门......
  • BZOJ 4747-4749题解 Usaco2016 Dec
    BZOJ4747:[Usaco2016Dec]CountingHaybales给出N(1≤N≤100,000)个数,和Q(1≤Q≤100,000)个询问。每个询问包含两个整数A,B(0≤A≤B≤1,000,000,000)。对于每个询问,给出数值......
  • Codeforces Round #395 (Div. 1) 题解
    ATimofeyandatree#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#defin......
  • Spring常见问题解决办法汇总
     解决Theprefix'context'forelement'context:component-scan'isnotbound<beansxmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://w......
  • P2044 [NOI2012] 随机数生成器
    #include<iostream>#include<cstring>usingnamespacestd;typedeflonglongll;llmod,a,c,x,n,g;namespaceksc{llksc(llx,lly){......
  • BSOJ7075题解
    感觉这一类DP至少不应该被叫做“LCS模型”,本质应该是其他的东西......先来考虑经典的LCS:\(dp[n][m]\)表示\(S[n]\)和\(T[m]\)匹配上的最长的长度。那么我们不妨......
  • GCJ 2017 R2 题解(待续)
    ProblemA.FreshChocolateProblemYouarethepublicrelationsmanagerforachocolatemanufacturer.Unfortunately,thecompany’simagehassufferedbecausecus......