Nowcode 建設道路

前幾天做了一個簡單題

思路

通過讀題我們很容易看出他就是讓我們求這麼一個東西:

\(\displaystyle\sum_{i = 1}^n \sum_{j = i + 1}^{n} (a_i - a_j)^2\)

我們把後邊的完全平方公式展開就是:

\(\displaystyle\sum_{i = 1}^n \sum_{j = i + 1}^{n} a_i^2 -2a_ia_J + a_j^2\)

顯然我們還可以把 \(a_i^2\)提出來

\(\displaystyle\sum_{i = 1}^n (n - i)a_i^2-2a_i\sum_{j = i + 1}^{n}a_J + \sum_{j = i + 1}^{n}a_j^2\)

顯然後邊的\(a_j\)\(a_j^2\)我們可以提前用前綴和處理

我們用sum[i]表示對a[i]數組的前綴和,用sum2表示對\(a[i]^2\)的前綴和

那麼原來的式子就能化成:

\(\displaystyle\sum_{i = 1}^n (n - i)a_i^2-2a_i*(sum[n] - sum[i])+ (sum2[n]-sum2[i])\)

最後的時候注意取膜就行了

code

#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <algorithm>

#define ll long long
#define N 500010
#define M 1010

using namespace std;
const int mod = 1000000007;
int n;
ll a[N], sum[N], sum2[N];

ll read() {
	ll s = 0, f = 0; char ch = getchar();
	while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
	return f ? -s : s;
}

int main() {
	n = read();
	for (int i = 1; i <= n; i++) {
		a[i] = read();
		sum[i] = (sum[i - 1] + a[i]) % mod;
		sum2[i] = (sum2[i - 1] + (a[i] * a[i]) % mod) % mod;
	}
	ll ans = 0;
	for (int i = 1; i <= n; i++) {
		ll x1 = ((n - i) * ((a[i] * a[i]) % mod)) % mod;
		ll x2 = ((2 * a[i] % mod) * ((sum[n] - sum[i] + mod) % mod)) % mod;
		ll x3 = (sum2[n] - sum2[i] + mod) % mod;
		ll x = (x1 - x2 + x3 + mod) % mod;
		ans = (ans + x) % mod;
	}
	cout << ans;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章