CodeForces-86D Powerful array 莫隊
阿新 • • 發佈:2018-11-26
CodeForces-86D Powerful array
題意: 給定一個區間計算power值, power[l, r] = sigma(sum[pi]*sum[pi]*pi).
分析: 莫隊來做, 對於add操作, 要累加的值為(sum[a[x]]*2 + 1)*a[x], del操作減去就行. 這個規律很好發現. 這道題卡常, 乘法用位操作替代. 輸出一定要I64d, 否則TLE.
程式碼:
#include <bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 10; const int MAXM = 1e6 + 10; struct Query { int l, r, id; } Q[MAXN]; int L = 1, R = 0; long long Ans = 0; long long ans[MAXN]; int flag[MAXM], pos[MAXN], a[MAXN]; int n, m; bool cmp(Query x, Query y) { if (pos[x.l] == pos[y.l]) { return x.r < y.r; } else { return pos[x.l] < pos[y.l]; } } inline int read() { int x = 0; char ch = getchar(); while (ch < '0' || ch > '9') ch = getchar(); while (ch <= '9' && ch >= '0') { x = x * 10 + ch - '0'; ch = getchar(); } return x; } inline void add(int x) { Ans += (((long long)(flag[a[x]]) << 1) + 1) * a[x]; flag[a[x]]++; return; } inline void del(int x) { flag[a[x]]--; Ans -= (((long long)(flag[a[x]]) << 1) + 1) * a[x]; return; } int main() { // cin.sync_with_stdio(false); // cin.tie(0); //scanf("%d%d", &n, &m); //cin >> n >> m; n = read(); m = read(); int unit = sqrt(1.0 * n); for (int i = 1; i <= n; i++) { //cin >> a[i]; a[i] = read(); pos[i] = i / unit + 1; } for (int i = 1; i <= m; i++) { Q[i].l = read(); Q[i].r = read(); Q[i].id = i; } sort(Q + 1, Q + m + 1, cmp); for (int i = 1; i <= m; i++) { if (Q[i].l == Q[i].r) { ans[Q[i].id] = 1l * a[Q[i].l]; continue; } while (L < Q[i].l) { del(L++); //L++; } while (L > Q[i].l) { //L--; add(--L); } while (R < Q[i].r) { //R++; add(++R); } while (R > Q[i].r) { del(R--); //R--; } ans[Q[i].id] = Ans; } for (int i = 1; i <= m; i++) { printf("%I64d\n", ans[i]); // cout << ans[i] << endl; } return 0; }