两两乘积之和
代码注释与解题思路
解题思路
这道题目要求计算一个整数序列中所有两两元素乘积的和(即对于所有i<j的组合,计算A_i × A_j并求和)。
直接使用双重循环计算所有i<j的组合会导致O(n²)的时间复杂度,这在n很大(如3×10⁵)时会非常低效。我们需要找到一种数学方法来优化计算。
关键数学推导
我们可以利用以下数学恒等式来优化计算:
(∑A_i)² = ∑A_i² + 2×∑(A_i×A_j) (其中i<j)
因此,所有两两乘积的和可以表示为:
∑(A_i×A_j) = [(∑A_i)² - ∑A_i²] / 2
这种方法将时间复杂度从O(n²)降低到O(n),只需要一次遍历即可计算出所有元素的和(sum)以及所有元素的平方和(s)。
代码注释
#include<bits/stdc++.h> // 包含所有标准库头文件
using namespace std;
#define ll long long // 定义ll为long long类型,用于处理大数
const int N = 3e5+5; // 定义最大可能的数组大小
// 定义全局变量
ll x, s, n, sum = 0; // x:临时存储输入元素, s:平方和, n:元素个数, sum:元素和
int main(){
cin >> n; // 读取元素个数n
// 遍历所有元素
for(int i = 1; i <= n; i++){
cin >> x; // 读取当前元素
sum += x; // 累加到元素和中
s = s + x * x; // 累加到平方和中
}
// 根据数学公式计算结果: (所有元素和的平方 - 平方和) / 2
ll ans = ((sum * sum) - s) / 2;
// 输出结果
cout << ans;
return 0;
}
示例解释
以样例1为例:
输入:
3
4
2
3
计算过程:
- sum = 4 + 2 + 3 = 9
- s = 4² + 2² + 3² = 16 + 4 + 9 = 29
- ans = (sum² - s)/2 = (81 - 29)/2 = 52/2 = 26
这与题目给出的输出一致,验证了算法的正确性。
这种方法高效地解决了大规模数据下的两两乘积求和问题,避免了O(n²)的时间复杂度。