2559. 数正方形

题目链接

2559. 数正方形

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

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

image

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

输入格式

输入包含一个整数 \(N\)

输出格式

输出一个整数代表答案。

数据范围

\(2≤N≤10^6\)

输入样例:

4

输出样例:

20

解题思路

规律

相当于在一个长度为 \(n\) 的正方形中找正方形的个数,对于一个长度为 \(k\) 的非斜正方形来说,其拥有的个数为 \((n-k+1)^2\),而一个长度为 \(k\) 的非斜正方形含有的最大斜正方形的个数为 \((k-1)\),分析如下:
image

所以总的正方形的个数为 \(\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;
}
posted @ 2022-04-04 09:12  zyy2001  阅读(180)  评论(0编辑  收藏  举报