[NowCoder5673E]Enigmatic Partition

题意

定义整数 n n n的拆分 n = a 1 + a 2 + . . . + a m n=a_1+a_2+...+a_m n=a1+a2+...+am为"enigmatic partition"为符合以下条件的拆分:

  1. a i ∈ Z a_i\in Z aiZ 1 ≤ a i ≤ n 1\le a_i\le n 1ain
  2. a i ≤ a i + 1 ≤ a i + 1 a_i\le a_{i+1}\le a_i+1 aiai+1ai+1
  3. a m = a 1 + 2 a_m=a_1+2 am=a1+2

f ( n ) f(n) f(n)表示 n n n有多少种不同的"enigmatic partition",求 ∑ i = l r f ( i ) \displaystyle\sum_{i=l}^rf(i) i=lrf(i).

1 ≤ l ≤ r ≤ 1 0 5 1\le l\le r\le10^5 1lr105


写在前面

考场上对 m m m分类打表归纳出了 f ( n ) f(n) f(n)的数学表达式,但是不知道如何用数学证明,如果有大佬知道怎么证明请联系一下我,谢谢。


题解

首先可以写一个爆搜

#include
using namespace std;
const int N=100+5;
int n,a[N],f[N];
void dfs(int m,int res){
	if(res<0)return;
	if(res==0){
		--m;
		if(a[m]==a[1]+2)++f[n];
		return;
	}
	a[m]=a[m-1];
	dfs(m+1,res-a[m]);
	if(a[m-1]<=a[1]+1){
		a[m]=a[m-1]+1;
		dfs(m+1,res-a[m]);
	}
}
int main(){
	for(n=1;n<=50;++n){
		for(int i=1;i<=n;++i)
			a[1]=i,
			dfs(2,n-i);
	}
	for(n=1;n<=50;++n)
		printf("%2d:%3d\n",n,f[n]);
    return 0;
}
n n n 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 15 15 15 16 16 16 17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22 22 22 23 23 23 24 24 24 25 25 25 26 26 26 27 27 27 28 28 28 29 29 29 30 30 30 31 31 31 32 32 32 33 33 33 34 34 34 35 35 35 36 36 36 37 37 37 38 38 38 39 39 39 40 40 40 41 41 41 42 42 42 43 43 43 44 44 44 45 45 45 46 46 46 47 47 47 48 48 48 49 49 49 50 50 50
f ( n ) f(n) f(n) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 4 4 4 4 4 4 6 6 6 9 9 9 10 10 10 11 11 11 17 17 17 17 17 17 21 21 21 24 24 24 28 28 28 31 31 31 38 38 38 37 37 37 45 45 45 50 50 50 56 56 56 56 56 56 68 68 68 69 69 69 78 78 78 83 83 83 91 91 91 94 94 94 107 107 107 106 106 106 122 122 122 126 126 126 136 136 136 137 137 137 155 155 155 158 158 158 171 171 171 176 176 176 190 190 190 193 193 193 214 214 214 211 211 211 231 231 231 238 238 238 254 254 254 256 256 256

粗略地看只有 f ( 2 k + 1 ) f(2k+1) f(2k+1) f ( 2 k + 2 ) f(2k+2) f(2k+2)相差较小,但和 f ( 2 k ) f(2k) f(2k)相差较大的规律。

通过简易分析,可知当 m = n − 2 , n − 3 m=n-2,n-3 m=n2,n3 n ≥ 8 n\ge8 n8时一定只有一种方案;当 m = n − 4 m=n-4 m=n4 n ≥ 9 n\ge9 n9时只有两种方案。

考虑对不同的 m m m进行分类打表:

int g[N][N];
void dfs(int m,int res){
	...
	if(res==0){
		--m;
		if(a[m]==a[1]+2)
			++g[n][m];
		return;
	}
	...
}
int main(){
	...
	for(n=1;n<=50;++n){
		printf("%2d:",n);
		for(int m=1;m<=n;++m)
			printf("%3d ",g[n][m]);
		puts("");
	}
	...
}

得到如下表格

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
1 0 0 0
2 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
10 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
11 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
12 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
13 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
14 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
15 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
16 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
17 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
18 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 2 2 2 2 2 2 2 2 2 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
19 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
20 0 0 0 0 0 0 0 0 0 1 1 1 2 2 2 1 1 1 2 2 2 2 2 2 3 3 3 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
21 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
22 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
23 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
24 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
25 0 0 0 0 0 0 0 0 0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
26 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
27 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
28 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 3 3 3 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
29 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
30 0 0 0 0 0 0 1 1 1 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
31 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
32 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
33 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
34 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
35 0 0 0 0 0 0 0 0 0 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
36 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 4 4 4 3 3 3 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
37 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
38 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
39 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
40 0 0 0 0 0 0 0 0 0 1 1 1 2 2 2 1 1 1 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
41 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
42 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 2 2 2 3 3 3 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
43 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
44 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 5 5 5 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 10 10 10 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
45 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
46 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 11 11 11 10 10 10 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
47 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 10 10 10 10 11 11 11 10 10 10 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
48 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 10 11 11 11 11 11 11 10 10 10 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
49 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 10 10 10 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
50 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 1 1 1 2 2 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 10 10 10 10 12 12 12 11 11 11 11 11 11 10 10 10 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0

可以看出非常明显的规律,特别的当 m ≥ n 2 m\ge\frac n2 m2n时, g [ n ] [ m ] g[n][m] g[n][m]的值为确定的常数,且每到偶数行就会多出一个常数,归纳后结果为 ⌊ n − 2 4 ⌋ \lfloor\frac{n-2}4\rfloor 4n2

m < n 2 m<\frac n2 m<2n时,继续观察可以发现:

  1. m = 2 k + 3 m=2k+3 m=2k+3时,这一列几乎全是 k k k,会出现少数 k + 1 k+1 k+1
  2. m = 2 k + 4 m=2k+4 m=2k+4时,这一列几乎全是 k k k k + 1 k+1 k+1交替出现,少量 k k k会变成 k + 1 k+1 k+1

事出反常必有妖,观察这些反常的 k + 1 k+1 k+1出现的规律,可以总结得到

  1. m = 2 k + 3 m=2k+3 m=2k+3时,反常的 k + 1 k+1 k+1出现在 2 k + 3 2k+3 2k+3的倍数行,即 m m m的倍数行。
  2. m = 2 k + 4 m=2k+4 m=2k+4时,反常的 k + 1 k+1 k+1出现在 2 k + 4 2k+4 2k+4的倍数行,即 m m m的倍数行。

大胆猜测, f ( n ) f(n) f(n)的值与其约数个数 d ( n ) d(n) d(n)有关。

任取 1 1 1行,对比其将反常的数修正前后的 g [ n ] [ m ] g[n][m] g[n][m],得到:

42 42 42 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
修正前 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 2 2 2 3 3 3 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
修正后 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 8 10 10 10 9 9 9 9 9 9 8 8 8 8 8 8 7 7 7 7 7 7 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0

可以发现所有 n n n的大于 2 2 2,小于 n 2 \frac n2 2n的约数列都出现了反常的 k + 1 k+1 k+1

总结一下前面的规律可以得到
f ( n ) − f ( n − 1 ) = 两行反常的k+1出现次数差 + 常数 \displaystyle f(n)-f(n-1)=\text{两行反常的k+1出现次数差}+\text{常数} f(n)f(n1)=两行反常的k+1出现次数差+常数

而每行反常的 k + 1 k+1 k+1出现次数又与 d ( n ) d(n) d(n)有关,通过进一步观察发现次数差恰好等于 d ( n ) − d ( n − 1 ) d(n)-d(n-1) d(n)d(n1)

回到最初的表格,算出 h ( n ) = f ( n ) − f ( n − 1 ) − [ d ( n ) − d ( n − 1 ) ] h(n)=f(n)-f(n-1)-[d(n)-d(n-1)] h(n)=f(n)f(n1)[d(n)d(n1)]

n n n 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 15 15 15 16 16 16 17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22 22 22 23 23 23 24 24 24 25 25 25 26 26 26 27 27 27 28 28 28 29 29 29 30 30 30 31 31 31 32 32 32 33 33 33 34 34 34 35 35 35 36 36 36 37 37 37 38 38 38 39 39 39 40 40 40 41 41 41 42 42 42 43 43 43 44 44 44 45 45 45 46 46 46 47 47 47 48 48 48 49 49 49 50 50 50
h ( n ) h(n) h(n) − 1 -1 1 − 1 -1 1 0 0 0 − 1 -1 1 1 1 1 − 1 -1 1 2 2 2 − 1 -1 1 3 3 3 − 1 -1 1 4 4 4 − 1 -1 1 5 5 5 − 1 -1 1 6 6 6 − 1 -1 1 7 7 7 − 1 -1 1 8 8 8 − 1 -1 1 9 9 9 − 1 -1 1 10 10 10 − 1 -1 1 11 11 11 − 1 -1 1 12 12 12 − 1 -1 1 13 13 13 − 1 -1 1 14 14 14 − 1 -1 1 15 15 15 − 1 -1 1 16 16 16 − 1 -1 1 17 17 17 − 1 -1 1 18 18 18 − 1 -1 1 19 19 19 − 1 -1 1 20 20 20 − 1 -1 1 21 21 21 − 1 -1 1 22 22 22 − 1 -1 1 23 23 23 − 1 -1 1

归纳得
h ( n ) = { − 1 , 2 ∣ n n − 3 2 , 2 ∤ n h(n)=\left\{\begin{aligned} &-1,&2\mid n\\ &\frac{n-3}2,&2\nmid n \end{aligned}\right. h(n)=1,2n3,2n2n

用累加法可以求得

f ( n ) − f ( 1 ) − [ d ( n ) − d ( 1 ) ] = ∑ i = 2 n h ( i ) = { − 2 k + ( k − 1 ) ( k − 2 ) 2 , n = 2 k + 1 − 2 k − 1 + ( k − 1 ) ( k − 2 ) 2 , n = 2 k + 2 f(n)-f(1)-[d(n)-d(1)]=\sum_{i=2}^nh(i)=\left\{\begin{aligned} &-2k+\frac{(k-1)(k-2)}2,&n=2k+1\\ &-2k-1+\frac{(k-1)(k-2)}2,&n=2k+2 \end{aligned}\right. f(n)f(1)[d(n)d(1)]=i=2nh(i)=2k+2(k1)(k2),2k1+2(k1)(k2),n=2k+1n=2k+2
其中 k = ⌊ n − 1 2 ⌋ k=\lfloor\frac{n-1}2\rfloor k=2n1,化简可得

f ( n ) = d ( n ) + 1 2 ⌊ n − 1 2 ⌋ 2 − 3 2 ⌊ n − 1 2 ⌋ − 1 2 [ 3 + ( − 1 ) n ] f(n)=d(n)+\frac12\lfloor\frac{n-1}2\rfloor^2-\frac32\lfloor\frac{n-1}2\rfloor-\frac12[3+(-1)^n] f(n)=d(n)+212n12232n121[3+(1)n]

s ( n ) = ∑ i = 1 n f ( i ) \displaystyle s(n)=\sum_{i=1}^nf(i) s(n)=i=1nf(i),令 k = ⌊ n − 1 2 ⌋ k=\lfloor\frac{n-1}2\rfloor k=2n1,当 n = 2 k + 1 n=2k+1 n=2k+1时,有
s ( n ) = f ( 2 k + 1 ) + ∑ i = 0 k − 1 [ f ( 2 i + 1 ) + f ( 2 i + 2 ) ] = ∑ i = 1 n d ( i ) + 1 2 ( k 2 − 3 k − 2 ) + ∑ i = 0 k − 1 ( i 2 − 3 i − 3 ) = ∑ i = 1 n d ( i ) + 1 2 ( k 2 − 3 k − 2 ) + ∑ i = 1 k − 1 i 2 − 3 ∑ i = 1 k − 1 i − 3 k \begin{aligned} s(n)&=f(2k+1)+\sum_{i=0}^{k-1}[f(2i+1)+f(2i+2)]\\ &=\sum_{i=1}^nd(i)+\frac12(k^2-3k-2)+\sum_{i=0}^{k-1}(i^2-3i-3)\\ &=\sum_{i=1}^nd(i)+\frac12(k^2-3k-2)+\sum_{i=1}^{k-1}i^2-3\sum_{i=1}^{k-1}i-3k \end{aligned} s(n)=f(2k+1)+i=0k1[f(2i+1)+f(2i+2)]=i=1nd(i)+21(k23k2)+i=0k1(i23i3)=i=1nd(i)+21(k23k2)+i=1k1i23i=1k1i3k

同理,当 n = 2 k + 2 n=2k+2 n=2k+2
s ( n ) = ∑ i = 1 n d ( i ) + ∑ i = 1 k i 2 − 3 ∑ i = 1 k i − 3 ( k + 1 ) s(n)=\sum_{i=1}^nd(i)+\sum_{i=1}^{k}i^2-3\sum_{i=1}^{k}i-3(k+1) s(n)=i=1nd(i)+i=1ki23i=1ki3(k+1)

其中 ∑ i = 1 n d ( i ) = ∑ i = 1 n ⌊ n i ⌋ \displaystyle\sum_{i=1}^nd(i)=\sum_{i=1}^n\lfloor\frac ni\rfloor i=1nd(i)=i=1nin可以根号分块处理, ∑ i = 1 k i 2 \displaystyle\sum_{i=1}^ki^2 i=1ki2 ∑ i = 1 k i \displaystyle\sum_{i=1}^ki i=1ki可以用求和公式 O ( 1 ) O(1) O(1)处理,故单次询问的复杂度为 O ( n ) O(\sqrt n) O(n )

算法一:线性筛+递推

时间复杂度 O ( n + T ) O(n+T) O(n+T)

#include 
using namespace std;
const int N = 1e5 + 5;
typedef long long ll;
int is[N], pr[N], d[N], c[N];
ll f[N], s[N];
int main() {
    int n = 1e5;
    d[1] = 1;
    for (int i = 2; i <= n; ++i) {
        if (!is[i])
            pr[++pr[0]] = i, d[i] = 2, c[i] = 1;
        for (int j = 1, x; j <= pr[0] && (x = i * pr[j]) <= n; ++j) {
            is[x] = 1;
            if (i % pr[j])
                c[x] = 1, d[x] = d[i] << 1;
            else {
                c[x] = c[i] + 1, d[x] = d[i] / c[x] * (c[x] + 1);
                break;
            }
        }
    }
    for (int i = 1; i <= n; ++i)
        f[i] = f[i - 1] + d[i] - d[i - 1] + (i & 1 ? (i - 3) / 2 : -1),
        s[i] = s[i - 1] + f[i];
    scanf("%*d");
    for (int i = 1, l, r; ~scanf("%d%d", &l, &r); ++i)
        printf("Case #%d: %lld\n", i, s[r] - s[l - 1]);
    return 0;
}

算法二:根号分块

时间复杂度 O ( T n ) O(T\sqrt n) O(Tn )

#include 
using namespace std;
typedef long long ll;
inline ll s1(int n) { return (ll)n * (n + 1) >> 1; }
inline ll s2(int n) { return (ll)n * (n + 1) * (n << 1 | 1) / 6; }
inline ll s(int n) {
    if (!n)
        return 0;
    int k = (n - 1) / 2, f = n & 1;
    ll Sum = n & 1 ? ((ll)k * (k - 3) - 2) >> 1 : 0ll;
    for (int i = 1, j; i <= n; i = j + 1) {
        j = n / (n / i);
        Sum += (ll)(n / i) * (j - i + 1);
    }
    Sum += s2(k - f) - 3 * s1(k - f) - 3 * (k + 1 - f);
    return Sum;
}
int main() {
    scanf("%*d");
    for (int i = 1, l, r; ~scanf("%d%d", &l, &r); ++i)
        printf("Case #%d: %lld\n", i, s(r) - s(l - 1));
    return 0;
}

后记

赛后发现,把此题扩展到 a m = a 1 + k a_m=a_1+k am=a1+k,对 m m m分类打出来的表找依旧很有规律,稍微总结一下应该也能做。

你可能感兴趣的:(数学,打表,算法,数学)