给定 n 个整数 a1, a2, · · · , an ,求它们两两相乘再相加的和,即 S = a1 · a2 + a1 · a3 + · · · + a1 · an + a2 · a3 + · · · + an-2 · an-1 + an-2 · an + an-1 · an.
输入格式输入的第一行包含一个整数 n 。
第二行包含 n 个整数 a1, a2, · · · an。
输出格式输出一个整数 S,表示所求的和。请使用合适的数据类型进行运算。
样例输入复制
4 1 3 6 9样例输出
复制
117提示
对于 30% 的数据,1 ≤ n ≤ 1000,1 ≤ ai ≤ 100。
对于所有评测用例,1 ≤ n ≤ 200000,1 ≤ ai ≤ 1000。
思路:两种做法
① 前缀和:
通过观察发现,可以把每一项提出来,则a[1] * (a[2] + a[3]+...+a[n]) 就等价于a[1] * (s[n] - s[1]),则可以用前缀和。
② 公式:
通过观察发现,所求的式子等价于 ((a[1]+a[2]+...+a[n]) ^ 2 - (a[1]^2 + a[2]^2+...+a[n]^2)) / 2
代码:#include暑期编程PK赛 得CSDN机械键盘等精美礼品!// 前缀和 using namespace std; #define endl "n" typedef long long ll; const int N = 2e5 + 10; int a[N]; ll s[N], sum; int main() { ios::sync_with_stdio(false); cout.tie(0); int n; cin >> n; for(int i = 1; i <= n; i ++) { cin >> a[i]; s[i] = s[i - 1] + a[i]; } for(int i = 1; i <= n - 1; i ++) { sum += (a[i] * (s[n] - s[i])); } cout << sum; return 0; } #include // 公式 using namespace std; #define endl "n" typedef long long ll; const int N = 2e5 + 10; ll a[N], sum, s; int main() { ios::sync_with_stdio(false); cout.tie(0); int n; cin >> n; for(int i = 1; i <= n; i ++) { cin >> a[i]; sum += a[i]; a[i] *= a[i]; s += a[i]; } cout << (sum * sum - s) / 2; return 0; }



