原题链接
3782. 点 - AcWing题库
目标需求
i<j∑n[(xi−xj)2+(yi−yj)2]=i<j∑n(xi−xj)2+i<j∑n(yi−yj)2
拆开 发现x,y相互独立 我们只研究x的部分y部分同理
i<j∑n(xi−xj)2=i<j∑n(xi2+xj2−2xixj)
分析
- 对于前两项平方和 i<j∑n(xi2+xj2)=i∑n(n−1)xi2
因为是求每两个数的距离和,那么对于任意一项xi需要和其他n−1项进行配对
而 xi2在一组配对计算中有且仅有一个,则对于n−1的配对中xi2会被加上n−1次
也就是说任意的xi2都会出现且仅出现n−1次,即i<j∑n(xi2+xj2)=i∑n(n−1)xi2
- 对于最后一项 i<j∑n2xixj=(i∑nxi)2−i∑nxi2
i<j∑n2xixj=i<j∑n(xixj+xjxi)=i,j∑nxixj
不考虑顺序的话任意的配对了 无论是xixj还是xjxi都会被计算一次
i,j∑nxixj=(x1+x2+⋯+xn)2−x12−x22−⋯xn2=(i∑nxi)2−i∑nxi2
将上述平方拆开就可以得到答案
别忘了这是2xiyi后面计算别忘了负号
结果
i<j∑n(xi−xj)2=i∑n(n−1)xi2−[(i∑nxi)2−i∑nxi2]=ni∑nxi2+(i∑nxi)2
同理
i<j∑n(yi−yj)2=i∑n(n−1)yi2−[(i∑nyi)2−i∑nyi2]=ni∑nyi2+(i∑nyi)2
总结
将上诉两者相加
i<j∑n[(xi−xj)2+(yi−yj)2]=ni∑n(xi2+yi2)−(i∑nxi)2−(i∑nyi)2
代码
代码中只需要三个变量
s
各个横纵坐标的平方和
sx
横坐标的和
sy
纵坐标的和
注意数据很大要开Long Long
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include<iostream> using namespace std; typedef long long LL; int n,x,y; LL s,sx,sy; int main(){ cin>>n; for(int i=0;i<n;i++){ cin>>x>>y; s+=x*x+y*y; sx+=x,sy+=y; } cout<<n*s-sx*sx-sy*sy<<endl; return 0; }
|