數組長度 n≤200,000,查詢 Q≤200,000。每查詢 [l,r] 求 Σ cnt[x]² * x,其中 cnt[x] 為 x 在區間內出現次數。
block = l / B,B = √n當元素 x 加入區間:
ans -= 1LL * cnt[x] * cnt[x] * x; cnt[x]++; ans += 1LL * cnt[x] * cnt[x] * x;
移除時反向操作(先減後加)。
struct Query { int l, r, id, block; };
bool cmp(Query a, Query b) {
if (a.block != b.block) return a.block < b.block;
return (a.block & 1) ? a.r > b.r : a.r < b.r; // 奇偶塊優化
}
int cnt[MAXA];
long long ans, curAns;
int L=1, R=0;
void add(int pos) {
int x = a[pos];
curAns -= 1LL * cnt[x] * cnt[x] * x;
cnt[x]++;
curAns += 1LL * cnt[x] * cnt[x] * x;
}
void remove(int pos) {
int x = a[pos];
curAns -= 1LL * cnt[x] * cnt[x] * x;
cnt[x]--;
curAns += 1LL * cnt[x] * cnt[x] * x;
}
int main() {
// 讀入、分塊、排序查詢
for (auto& q : queries) {
while (L > q.l) add(--L);
while (R < q.r) add(++R);
while (L < q.l) remove(L++);
while (R > q.r) remove(R--);
ans[q.id] = curAns;
}
// 輸出答案
}
cnt 替代 unordered_map