2559. 数正方形
题目链接
2559. 数正方形
在一个 \(N×N\) 的点阵上,取其中 \(4\) 个点恰好组成一个正方形的 \(4\) 个顶点,一共有多少种不同的取法?
由于结果可能非常大,你只需要输出模 \(10^9+7\) 的余数。
如上图所示的正方形都是合法的。
输入格式
输入包含一个整数 \(N\)。
输出格式
输出一个整数代表答案。
数据范围
\(2≤N≤10^6\)
输入样例:
4
输出样例:
20
解题思路
规律
相当于在一个长度为 \(n\) 的正方形中找正方形的个数,对于一个长度为 \(k\) 的非斜正方形来说,其拥有的个数为 \((n-k+1)^2\),而一个长度为 \(k\) 的非斜正方形含有的最大斜正方形的个数为 \((k-1)\),分析如下:
所以总的正方形的个数为 \(\sum_{i=1}^nf[i]+\sum_{i=2}^nf[i]\times (i-1)\)
- 时间复杂度:\(O(n)\)
代码
// %%%Skyqwq
#include <bits/stdc++.h>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
// #define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
using namespace tr1;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
const int N=1e6+5,mod=1e9+7;
LL f[N];
int n;
int main()
{
cin>>n;
n--;
LL res=0;
for(int i=1;i<=n;i++)f[i]=1ll*(n-i+1)*(n-i+1)%mod,res=(res+f[i]%mod);
for(int i=2;i<=n;i++)res=(res+1ll*f[i]*(i-1))%mod;
cout<<res;
return 0;
}