From 1ac4f8977abc111767c9e5a4fa3abee3ca71bb2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com> Date: Thu, 14 Dec 2023 11:12:40 +0800 Subject: [PATCH] 'commit' --- TangDou/Topic/SpareTire.cpp | 79 +++++++++++++---------------------- TangDou/Topic/SpareTire.in | 1 + TangDou/Topic/容斥原理.md | 68 +++++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 50 deletions(-) create mode 100644 TangDou/Topic/SpareTire.in diff --git a/TangDou/Topic/SpareTire.cpp b/TangDou/Topic/SpareTire.cpp index 607dfd4..59ba4eb 100644 --- a/TangDou/Topic/SpareTire.cpp +++ b/TangDou/Topic/SpareTire.cpp @@ -1,67 +1,49 @@ -#include -#include -#include +#include using namespace std; - -typedef long long LL; +#define int long long +#define endl "\n" const int maxn = 10000; -const LL Six = 166666668; /// 6,2关于mod的乘法逆元 -const LL Two = 500000004; -const LL mod = 1e9 + 7; /// 尽量这样定义mod ,减少非必要的麻烦 - -bool book[maxn]; -int pri[1300], cnt; /// 素数表 -int factor[130]; /// 因子表 +const int Six = 166666668; /// 6,2关于mod的乘法逆元 +const int Two = 500000004; +const int mod = 1e9 + 7; /// 尽量这样定义mod ,减少非必要的麻烦 -void Prime() { - memset(book, 0, sizeof(book)); - cnt = 0; - book[0] = book[1] = 1; - for (int i = 2; i < maxn; i++) { - if (!book[i]) - pri[cnt++] = i; - for (int j = 0; j < cnt && pri[j] * i < maxn; j++) { - book[i * pri[j]] = 1; - if (i % pri[j] == 0) - break; - } - } -} - -inline LL Mod(LL a, LL b) { +inline int Mod(int a, int b) { return (a % mod) * (b % mod) % mod; } -inline LL F(LL k, LL n) { /// 求(k*n)^2+k*n +inline int F(int k, int n) { /// 求(k*n)^2+k*n return (Mod(k, k) * Mod(Mod(n, n + 1), Mod(n + n + 1, Six)) % mod + Mod(Mod(1 + n, n), Mod(k, Two))) % mod; } -int main() { - LL n, m; - Prime(); - while (~scanf("%lld%lld", &n, &m)) { - int fac_cnt = 0; /// 素数因子的个数 +vector p; // 将m拆分成的质数因子序列p + +signed main() { +#ifndef ONLINE_JUDGE + freopen("SpareTire.in", "r", stdin); +#endif + int n, m; - for (int i = 0; i < cnt; i++) { - if (pri[i] > m) break; - if (m % pri[i] == 0) { - factor[fac_cnt++] = pri[i]; - while (m % pri[i] == 0) m /= pri[i]; + while (cin >> n >> m) { + int sum = F(1, n), ans = 0; /// 计算总和sum + + int t = m; // 复制出来 + for (int i = 2; i * i <= t; i++) { + if (t % i == 0) { + p.push_back(i); + while (t % i == 0) t = t / i; } } - if (m > 1) factor[fac_cnt++] = m; - - LL sum = F(1LL, n), ans = 0; /// 计算总和sum + if (t > 1) p.push_back(t); - LL item = 1 << fac_cnt; /// 开始容斥 + int item = 1 << p.size(); /// 开始容斥 - /// 例如有3个因子,那么item=1<<3=8(1000二进制) - /// 然后i从1开始枚举直到7(111二进制),i中二进制的位置1表式取这个位置的因子 - /// 例如i=3(11二进制) 表示去前两个因子,i=5(101)表示取第1个和第3个的因子 + // 例如有3个因子,那么item=1<<3=8(1000二进制) + // 然后i从1开始枚举直到7(111二进制),i中二进制的位置1表式取这个位置的因子 + // 例如i=3(11二进制) 表示去前两个因子,i=5(101)表示取第1个和第3个的因子 for (int i = 1; i < item; i++) { int num = 0, x = 1; - for (int j = 0; j < fac_cnt; j++) { - if (1 & (i >> j)) num++, x *= factor[j]; + for (int j = 0; j < p.size(); j++) { + if (1 & (i >> j)) num++, x *= p[j]; } if (num & 1) @@ -72,5 +54,4 @@ int main() { printf("%lld\n", ((sum - ans) % mod + mod) % mod); } - return 0; } diff --git a/TangDou/Topic/SpareTire.in b/TangDou/Topic/SpareTire.in new file mode 100644 index 0000000..f4eea7b --- /dev/null +++ b/TangDou/Topic/SpareTire.in @@ -0,0 +1 @@ +4 4 \ No newline at end of file diff --git a/TangDou/Topic/容斥原理.md b/TangDou/Topic/容斥原理.md index 63ef982..e632bee 100644 --- a/TangDou/Topic/容斥原理.md +++ b/TangDou/Topic/容斥原理.md @@ -930,7 +930,73 @@ int main() { #### 解题思路 -根据递推式,易求得$a[n]=n*n+n$,那么易得前$n$项和为 $Sn=n*(n+1)(2*n+1)/6+n*(n+1)/2$;我们直接求与$m$互质的数较难,所以我们可以换个思路,求与 $m$不互质的数,那么与$m$不互质的数,是取$m$的素因子的乘积(因为根据唯一分解定理,任意个数都可看作的素数积),那么我们将$m$分解质因数,通过容斥定理,就可以得道与$m$不互质的数,总和$sum$减去这些数对应的$a$的和就是答案了。 + +**结论**:递推式 $\large a_n = \frac{3a_{n-1} - a_{n-2}}{2} + n + 1$ 的通项公式为 $a_n = n^2 + n$。 + +可以使用数学归纳法来证明这个结论。 + +**初值条件** +当 $n = 1$ 时,$a_1 = 1^2 + 1 = 2$,符合通项公式 $a_n = n^2 + n$。 +当 $n = 2$ 时,$a_2 = 2^2 + 2 = 6$,符合通项公式 $a_n = n^2 + n$。 + +**归纳假设** +假设对于所有的 $n \leq m$,递推式 $a_n = \frac{3a_{n-1} - a_{n-2}}{2} + n + 1$ 的通项公式成立,即 $a_n = n^2 + n$。 + +**归纳步骤** +我们需要证明当 $n = m+1$ 时,通项公式 $a_n = n^2 + n$ 仍然成立。 + +根据递推式 $a_n = \frac{3a_{n-1} - a_{n-2}}{2} + n + 1$,我们有: + +$a_{m+1} = \frac{3a_m - a_{m-1}}{2} + m + 1+1 $ + +根据归纳假设,将 $a_m$ 和 $a_{m-1}$ 替换为 $(m^2 + m)$ 和 $((m-1)^2 + (m-1))$,得到: + +$a_{m+1} = \frac{3(m^2 + m) - ((m-1)^2 + (m-1))}{2} + m + 1+1 \rightarrow$ +$a_{m+1}=\frac{3m^2+3m-(m^2-2m+1)-m+1}{2}+m+1+1 \rightarrow$ +$a_{m+1}=\frac{3m^2+3m-m^2+2m-1-m+1}{2}+m+1+1 \rightarrow$ +$a_{m+1}=\frac{2m^2+4m}{2}+m+1+1 \rightarrow$ +$a_{m+1} = m^2 + 2m +m+1+ 1 \rightarrow $ +$a_{m+1} = m^2 + 2m +1+m+1 \rightarrow $ +$a_{m+1}= (m+1)^2 + (m+1) $ + +因此,当 $n = m+1$ 时,通项公式 $a_n = n^2 + n$ 仍然成立。 + +综上所述,根据数学归纳法,递推式 $a_n = \frac{3a_{n-1} - a_{n-2}}{2} + n + 1)$ 的通项公式为 $a_n = n^2 + n$ + +费了牛劲,终于求得$a_n=n*n+n$,那么前$n$项和$S_n$是多少呢? +即$S_n=a_1+a_2+a_3+...+a_n \rightarrow$ +$S_n=1^2+1+2^2+2+3^2+3+...+n^2+n$ +拆开来看: +① $1,2,3,...,n$很显然是一个等差数列,$S_n'=(1+n)*n/2$ +② $1^2,2^2,3^2,...,n^2$这个序列的求和公式是多少呢? +这是自然数平方求和数列,有公式: +$$\large S_n''=n*(n+1)(2*n+1)/6$$; + +这个东西是怎么来的呢? + +**推导过程** +$2³-1³=3×1²+3×1+1$ +$3³-2³=3×2²+3×2+1$ +$4³-3³=3×3²+3×2+1$ +... ... +$(n+1)³-n³=3n²+3n+1$ + +以上$n$个式子相加,得 +$(n+1)³-1=3(1²+2²+3²+...+n²)+3(1+2+3+...+n)+(1+1+1+...+1)$ +即$(n+1)³-1=3(1²+2²+3²+...+n²)+3[n(n+1)/2]+n$ + +令$S''=1²+2²+3²+...+n²$ +$3S''=(n+1)³-1-3n(n+1)/2-n$ +$3S''=(n+1)³-3n(n+1)/2-(n+1)$ +$3S''=(n+1)((n+1)^2-3n/2-1)$ +$S''=(n+1)(n^2+2n+1-3/2n-1)/3$ +$S''=(n+1)(n^2+n/2)/3$ +$S''=(n+1)(2n^2+n)/6$ +∴$S''=n(n+1)(2n+1)/6$。 + +> **更多推导方法,看 [《具体数学》学习笔记: $4$.四种方法推导平方和公式](https://blog.csdn.net/ajaxlt/article/details/86161674)** + +我们直接求与$m$互质的数较难,所以我们可以换个思路,求与 $m$不互质的数,那么与$m$不互质的数,是取$m$的素因子的乘积(因为根据唯一分解定理,任意个数都可看作的素数积),那么我们将$m$分解质因数,通过容斥定理,就可以得道与$m$不互质的数,总和$sum$减去这些数对应的$a$的和就是答案了。 $Sample$ $Input$ ```cpp {.line-numbers}