At coder C题推公式

97 阅读1分钟

题意

给定一个式子

i=2Nj=1i1(AiAj)2 \sum_{i=2}^N\sum_{j = 1}^{i - 1} {(A_i - A_j)} ^ 2

要求算出该式的.

数据范围: 1n3×1051\leq n \leq {3 \times 10 ^ 5}

通过题目我们发现,这个式子直接暴力算肯定会爆时间O(n2)O(n ^ 2)

通过这个式子我们可以推导一下

i=2Nj=1i1Ai×Aj=i=2Nj=1i1Ai22AiAj+Aj2 \sum_{i=2}^N\sum_{j = 1}^{i - 1} A_i \times A_j = \sum_{i=2}^N\sum_{j = 1}^{i - 1} {{A_i ^ 2 - 2 * A_i * A_j + A_j^2}}

我们将式子从左到右分成三个部分

  • 对于第一个式子 i=2Nj=1i1Ai2\sum_{i=2}^N\sum_{j = 1}^{i - 1} A_i ^ 2 = (i1)i=2NAi2(i - 1) * \sum_{i=2}^NA_i^ 2
  • 对于第二个式子 2i=2Nj=1i1AiAj2 * \sum_{i=2}^N\sum_{j = 1}^{i - 1} A_i * A_j = 2i=1NAij=2NAj2 *\sum_{i=1}^NA_i \\* \sum_{j = 2}^N A_j 对于后面这个类和式可以使用前缀和优化
  • 对于第三个式子 (Ni)i=1N1Ai2(N - i)\sum_{i=1}^{N-1}A_i^2

以上的式子,请把每个式子展开,大家就会发现这个规律

结论

i=2Nj=1i1(AiAj)2=(i1)i=2NAi22i=2NAij=2NAj+(Ni)i=1N1Ai2 \sum_{i=2}^N\sum_{j = 1}^{i-1}{(A_i - A_j) ^ 2} =(i - 1) * \sum_{i=2}^N A_i^2 - 2 * \sum_{i=2}^N A_i \sum_{j=2}^{N} A_j + (N - i) * \sum_{i=1}^{N-1}A_i^2

挂个链接 www.luogu.com.cn/problem/AT_…

#include <iostream>  
#include <cstring>  
#include <algorithm>  
#include <vector>  
  
#define LL  long long  
#define PII std::pair<int , int>  
  
const int N = 300010;  
  
int n;  
LL  AI , AJ , AIJ;  
LL A[N];  
  
int main(){  
  
  
    std::cin >> n;  
    std::vector<intv(n + 1);  
    for (int i = 1; i <= n; i ++ ) std::cin >> v[i];  
  
    for (int i = 2; i <= n; i ++ ) A[i] = A[i - 1] + v[i];  
  
    for (int i = 2; i <= n; i ++ ) AI += 1LL * (i - 1) * v[i] * v[i];              // ∑Ai^2  
    for (int i = 1; i < n; i ++ ) AJ += 1LL * (n - i) * v[i] * v[i];  
    for (int i = 1; i <= n; i ++ ) AIJ += 1LL * v[i] * (A[n] - A[i]);  
  
    LL ans = AI + AJ - 2 * AIJ;  
      
   std::cout << ans << '\n';   
  
    return 0;  
}