点(数学)
递推关系:
根据题意,列出以下方程
S
=
∑
i
1
n
(
x
i
−
∑
j
=
1
n
x
j
)
2
+
∑
i
,
j
=
1
n
(
y
i
−
∑
j
=
1
n
y
j
)
2
(1)
S = \sum_{i1}^{n}(x_i- \sum_{j=1}^{n}x_j)^2+\sum_{i,j=1}^{n}(y_i-\sum_{j=1}^{n}y_j)^2\tag{1}
S=i1∑n(xi−j=1∑nxj)2+i,j=1∑n(yi−j=1∑nyj)2(1)
单独考虑
x
x
x
S
=
∑
i
,
j
=
1
n
(
x
i
2
+
x
j
2
−
(
x
i
x
j
+
x
j
x
i
)
)
(2)
S = \sum_{i,j=1}^{n}(x_i^2+x_j^2-(x_ix_j+x_jx_i))\tag{2}
S=i,j=1∑n(xi2+xj2−(xixj+xjxi))(2)
相当于与每一个其它点做一次差,所以有
n
−
1
n-1
n−1个平方项,后面的部分每一个
i
i
i和其余
j
j
j都要有两次交叉相乘项
S
=
∑
i
n
(
n
−
1
)
x
i
2
−
(
(
∑
i
=
1
n
x
i
)
2
−
∑
i
=
1
n
x
i
2
)
(3)
S = \sum_{i}^{n}(n-1)x_i^2-((\sum_{i=1}^nx_i)^2-\sum_{i=1}^nx_i^2)\tag{3}
S=i∑n(n−1)xi2−((i=1∑nxi)2−i=1∑nxi2)(3)
预先处理平方和和和的平方,可以在
O
(
n
)
O(n)
O(n)的时间之内算出来结果
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int x[N], y[N];
LL get(int x[])
{
LL s1 = 0, s2 = 0;
for (int i = 0; i < n; i ++ )
{
s1 += x[i] * x[i];
s2 += x[i];
}
return (n - 1) * s1 - s2 * s2 + s1;
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ )
{
cin >> x[i] >> y[i];
}
cout << get(x) + get(y) << endl;
return 0;
}
408

被折叠的 条评论
为什么被折叠?



