P8692 [蓝桥杯 2019 国 C] 数正方形 O(n)优化到O(1) 题解及自出拓展题分享

前言

本人在教学过程中出过一道和本题类似,但是要比本题难度略高的一道同类题目,放在末尾,有需要的小伙伴可以自行挑战一下。

P8692 [蓝桥杯 2019 国 C] 数正方形

题目传送门

题目描述

在一个 N × N N \times N N×N 的点阵上,取其中 4 4 4 个点恰好组成一个正方形的 4 4 4 个顶点,一共有多少种不同的取法?

由于结果可能非常大,你只需要输出模 1 0 9 + 7 10^9 + 7 109+7 的余数。

如上图所示的正方形都是合法的。

输入格式

输入包含一个整数 N N N

输出格式

输出一个整数代表答案。

输入输出样例 #1

输入 #1

4

输出 #1

20

说明/提示

对于所有评测用例, 2 ≤ N ≤ 1 0 6 2 ≤ N ≤ 10^6 2N106

思路分析

对于一个 n × n n \times n n×n 的点阵,其实可以看做为一个边长为 ( n − 1 ) × ( n − 1 ) (n-1) \times (n-1) (n1)×(n1) 的矩阵,所以最大的正方形边长为 n − 1 n - 1 n1

正方形的形态共两种,正正方形,斜正方形
斜正方形暂且考虑四个顶点全部坐落在最大正方形边长上的情况,虽然存在斜正方形坐落在大正方形的内部,但是我们可以将其转化为边长更小的正方形坐落在最大边长的子情况讨论。

f ( 5 ) f(5) f(5) 表示边长为 5 5 5 的正方形个数,所以下图的情况可以转化为求第一个 f ( 4 ) f(4) f(4) 正方形的子情况。该正方形的四个顶点都是坐落于 f ( 4 ) f(4) f(4) 正方形的最外围边长上的。

在这里插入图片描述
下图中标黄色的部分的三角形不难证明是均是互相全等的三角形。

所以我们在考虑坐落于最大边的斜正方形时,直接考虑距离四角的位置即可,下图的红框正方形既可以理解为距离四角位置为 1 1 1,也可以理解为距离四角位置为 3 3 3,不难发现,斜正方形有对称性。
在这里插入图片描述
若斜正方形的顶点坐落在最大边上距离四角的距离为 0 0 0,就转化成了正正方形,如下图所示:
在这里插入图片描述
所以我们可以将正正方形,和斜正方形统一讨论,即 距离最大边四个角的距离

所以设最大边边长为 k k k k ∈ [ 1 , n − 1 ] k \in [1, n - 1] k[1,n1],设在最大边边长上,选取点距四个角的距离为 d d d,那么有 0 ≤ d ≤ k − 1 0 \le d \le k - 1 0dk1,共有 k − 1 − 0 + 1 = k k - 1 - 0 + 1 = k k10+1=k 种情况可选,即边长为 k k k 的正方形,顶点坐落于最大边的正方形共 k k k 个。

设边长为 i , i ∈ [ 1 , n ) i, i \in [1, n) i,i[1,n) 在最大为 n × n n \times n n×n 的正方形内共有 ( n − i ) × ( n − i ) (n - i) \times (n - i) (ni)×(ni) 个边长为 i i i 的正方形,每个正方形内根据上述推导共有 i − 1 − 0 + 1 = i i - 1 - 0 + 1 = i i10+1=i 种四个顶点坐落在 i i i 边长上的正方形,所以根据乘法原理,我们可以推出:
f ( n ) = ∑ i = 1 n − 1 i × ( n − i ) 2 f(n) = \sum_{i = 1}^{n - 1}i\times(n-i)^2 f(n)=i=1n1i×(ni)2

这样我们就有了本题的 O ( n ) O(n) O(n) 复杂度的算法。

代码块

#include <bits/stdc++.h>
using namespace std;
const int p = 1e9 + 7;
long long n, ans;
int main() {
	cin >> n;
	for (long long i = 1; i < n; i++) {
		ans = (ans + i * (n - i) % p * (n - i)) % p;
	}
	cout << ans;
	return 0;
}

优化

观察 f ( n ) = ∑ i = 1 n − 1 i × ( n − i ) 2 f(n) = \sum_{i = 1}^{n - 1}i\times(n-i)^2 f(n)=i=1n1i×(ni)2,可以尝试对该公式进行化简去 ∑ \sum_{}^{} 符号,转化成 O ( 1 ) O(1) O(1) 的数学公式。

以下是公式变换过程:
f ( n ) = ∑ i = 1 n − 1 i × ( n − i ) 2 = ∑ i = 1 n − 1 i × ( n 2 − 2 i n + i 2 ) = ∑ i = 1 n − 1 i n 2 − 2 i 2 n + i 3 = ∑ i = 1 n − 1 i n 2 − ∑ i = 1 n − 1 2 i 2 n + ∑ i = 1 n − 1 i 3 = n 2 ∑ i = 1 n − 1 i − 2 n ∑ i = 1 n − 1 i 2 + ∑ i = 1 n − 1 i 3 \begin{align*} f(n) & = \sum_{i = 1}^{n - 1}i\times(n-i)^2 \\ & = \sum_{i = 1}^{n - 1}i \times (n^2 - 2in + i^2) \\ & = \sum_{i = 1}^{n - 1} in^2 - 2i^2n + i^3 \\ & = \sum_{i = 1}^{n - 1} in^2 - \sum_{i = 1}^{n - 1}2i^2n + \sum_{i = 1}^{n - 1}i^3\\ & = n^2\sum_{i = 1}^{n - 1}i - 2n\sum_{i = 1}^{n - 1}i^2 + \sum_{i = 1}^{n - 1}i^3 \end{align*} f(n)=i=1n1i×(ni)2=i=1n1i×(n22in+i2)=i=1n1in22i2n+i3=i=1n1in2i=1n12i2n+i=1n1i3=n2i=1n1i2ni=1n1i2+i=1n1i3

不难发现,公式中出现了高斯公式,平方和公式和立方和公式。
已知:
∑ i = 1 n i = n × ( n + 1 ) 2 ∑ i = 1 n i 2 = n ( n + 1 ) ( 2 n + 1 ) 6 ∑ i = 1 n i 3 = [ n × ( n + 1 ) 2 ] 2 \begin {align*} &\sum_{i=1}^{n}i = \frac{n\times(n + 1)}{2} \\ &\sum_{i=1}^{n} i^2 = \frac{n(n+1)(2n+1)}{6} \\ &\sum_{i=1}^{n} i^3 = \left[\frac{n \times(n + 1)}{2}\right]^2 \end {align*} i=1ni=2n×(n+1)i=1ni2=6n(n+1)(2n+1)i=1ni3=[2n×(n+1)]2

所以对上式进行化简:
f ( n ) = n 2 ∑ i = 1 n − 1 i − 2 n ∑ i = 1 n − 1 i 2 + ∑ i = 1 n − 1 i 3 = n 2 × ( n − 1 ) × n 2 − 2 n × ( n − 1 ) × n × ( 2 n − 1 ) 6 + [ ( n − 1 ) × n 2 ] 2 = n 3 ( n − 1 ) 2 − n 2 ( n − 1 ) ( 2 n − 1 ) 3 + n 2 ( n − 1 ) 2 4 = 6 n 3 ( n − 1 ) 12 − 4 n 2 ( n − 1 ) ( 2 n − 1 ) 12 + 3 n 2 ( n − 1 ) 2 12 = 6 n 4 − 6 n 3 12 − ( 4 n 3 − 4 n 2 ) ( 2 n − 1 ) 12 + 3 n 2 ( n 2 − 2 n + 1 ) 12 = 6 n 4 − 6 n 3 − 8 n 4 + 4 n 3 + 8 n 3 − 4 n 2 + 3 n 4 − 6 n 3 + 3 n 2 12 = ( 6 − 8 + 3 ) n 4 + ( − 6 + 4 + 8 − 6 ) n 3 + ( − 4 + 3 ) n 2 12 = n 4 − n 2 12 = n 2 ( n + 1 ) ( n − 1 ) 12 \begin{align*} f(n) & = n^2\sum_{i = 1}^{n - 1}i - 2n\sum_{i = 1}^{n - 1}i^2 + \sum_{i = 1}^{n - 1}i^3 \\ &= n^2\times\frac{(n-1)\times n}{2} - 2n\times\frac{(n-1)\times n \times (2n - 1)}{6} + \left[\frac{(n-1) \times n}{2}\right]^2 \\ &= \frac{n^3(n-1)}{2} - \frac{n^2(n-1)(2n-1)}{3} + \frac{n^2(n-1)^2}{4} \\ &= \frac{6n^3(n-1)}{12} - \frac{4n^2(n-1)(2n-1)}{12} + \frac{3n^2(n-1)^2}{12}\\ &= \frac{6n^4-6n^3}{12} - \frac{(4n^3-4n^2)(2n-1)}{12} + \frac{3n^2(n^2-2n+1)}{12}\\ &= \frac{6n^4-6n^3-8n^4+4n^3+8n^3-4n^2+3n^4-6n^3+3n^2}{12} \\ &= \frac{(6-8+3)n^4 + (-6+4+8-6)n^3 + (-4 + 3)n^2}{12} \\ &= \frac{n^4 - n^2}{12} = \frac{n^2(n + 1)(n - 1)}{12} \end {align*} f(n)=n2i=1n1i2ni=1n1i2+i=1n1i3=n2×2(n1)×n2n×6(n1)×n×(2n1)+[2(n1)×n]2=2n3(n1)3n2(n1)(2n1)+4n2(n1)2=126n3(n1)124n2(n1)(2n1)+123n2(n1)2=126n46n312(4n34n2)(2n1)+123n2(n22n+1)=126n46n38n4+4n3+8n34n2+3n46n3+3n2=12(68+3)n4+(6+4+86)n3+(4+3)n2=12n4n2=12n2(n+1)(n1)

因为本题需要计算的是 f ( n ) % 1000000007 f(n) \% 1000000007 f(n)%1000000007 后的结果,所以通过最终推出的 O ( 1 ) O(1) O(1) 公式不难看出,本题存在了除后取模的问题,所以考虑计算 1 2 − 1 12^{-1} 121,即 12 × x ≡ 1 ( m o d 1000000007 ) 12\times x\equiv 1 \pmod{1000000007} 12×x1(mod1000000007),因为 1 e 9 + 7 1e9 + 7 1e9+7 是一个通用质数,考虑费马小定理,即 1 2 − 1 ≡ 1 2 1000000007 − 2 ( m o d 1 e 9 + 7 ) 12^{-1} \equiv 12^{1000000007 - 2} \pmod{1e9 + 7} 1211210000000072(mod1e9+7),通过快速幂代码快速计算可得 1 2 − 1 = 83333334 12^{-1} = 83333334 121=83333334

所以最终得出 O ( 1 ) O(1) O(1) 公式为:
f ( n ) = n 2 ( n + 1 ) ( n − 1 ) × 83333334 % m o d 。 f(n) = n^2(n+1)(n-1) \times 83333334 \% mod。 f(n)=n2(n+1)(n1)×83333334%mod

代码块

#include <bits/stdc++.h>
using namespace std;
const int p = 1e9 + 7;
long long n;
int main() {
	cin >> n;
	cout << n * n % p * (n + 1) % p * (n - 1) % p * 83333334 % p;
	return 0;
}

本题的数据范围是可以继续提高到 1 0 9 10^9 109的(误)。

三角形晶格传送门
本题的满分是 O ( 1 ) O(1) O(1) 1 0 9 10^9 109的数据,需要考虑逆元,推导过程因为是三角形涉及正逆三角形,所以和 n n n 的奇偶性相关,比本题略难

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量子鸿蒙信息学陈老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值