两两乘积之和

代码注释与解题思路

解题思路

这道题目要求计算一个整数序列中所有两两元素乘积的和(即对于所有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

计算过程:

  1. sum = 4 + 2 + 3 = 9
  2. s = 4² + 2² + 3² = 16 + 4 + 9 = 29
  3. ans = (sum² - s)/2 = (81 - 29)/2 = 52/2 = 26

这与题目给出的输出一致,验证了算法的正确性。

这种方法高效地解决了大规模数据下的两两乘积求和问题,避免了O(n²)的时间复杂度。

posted @ 2025-05-11 17:51  季风起  阅读(10)  评论(0)    收藏  举报