莫队算法+离散化
1.map会TLE,必须离散化做
2.long long会WA,__int64定义 %I64d输出输出能AC
3.注意输入的序列会爆int
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<map> #include<algorithm> using namespace std; const int maxn = 100000 + 10; int n, m; __int64 tmp[maxn], a[maxn], lsh[maxn]; int cnt; int pos[maxn]; __int64 c[maxn]; __int64 ans[maxn], Ans; int L, R; struct X { int l, r, id; }s[maxn]; bool cmp(const X&a, const X&b) { if (pos[a.l] == pos[b.l]) return a.r < b.r; return a.l < b.l; } int f(__int64 x) { int l = 1, r = cnt; while (l <= r) { int mid = (l + r) / 2; if (lsh[mid] < x) l = mid + 1; else if (lsh[mid]>x) r = mid - 1; else return mid; } } void LSH() { sort(tmp + 1, tmp + 1 + n); cnt = 0, lsh[++cnt] = tmp[1]; for (int i = 2; i <= n; i++) { if (tmp[i] == tmp[i - 1]) continue; lsh[++cnt] = tmp[i]; } for (int i = 1; i <= n; i++) a[i] = (__int64)f(a[i]); } int main() { while (~scanf("%d", &n)) { memset(c, 0, sizeof c); int sz = sqrt(1.0*n); for (int i = 1; i <= n; i++) { pos[i] = i / sz; scanf("%I64d", &tmp[i]); a[i] = tmp[i]; } LSH(); scanf("%d", &m); for (int i = 1; i <= m; i++) { scanf("%d%d", &s[i].l, &s[i].r); s[i].id = i; } sort(s + 1, s + 1 + m, cmp); Ans = 0; for (int i = s[1].l; i <= s[1].r; i++) { Ans = Ans - c[a[i]] * c[a[i]] * c[a[i]]; c[a[i]]++; Ans = Ans + c[a[i]] * c[a[i]] * c[a[i]]; } ans[s[1].id] = Ans; L = s[1].l; R = s[1].r; for (int i = 2; i <= m; i++) { while (L < s[i].l) { Ans = Ans - c[a[L]] * c[a[L]] * c[a[L]]; c[a[L]]--; Ans = Ans + c[a[L]] * c[a[L]] * c[a[L]]; L++; } while (L > s[i].l) { L--; Ans = Ans - c[a[L]] * c[a[L]] * c[a[L]]; c[a[L]]++; Ans = Ans + c[a[L]] * c[a[L]] * c[a[L]]; } while (R < s[i].r) { R++; Ans = Ans - c[a[R]] * c[a[R]] * c[a[R]]; c[a[R]]++; Ans = Ans + c[a[R]] * c[a[R]] * c[a[R]]; } while (R > s[i].r) { Ans = Ans - c[a[R]] * c[a[R]] * c[a[R]]; c[a[R]]--; Ans = Ans + c[a[R]] * c[a[R]] * c[a[R]]; R--; } ans[s[i].id] = Ans; } for (int i = 1; i <= m; i++) printf("%I64d\n", ans[i]); } return 0; }
原文:http://www.cnblogs.com/zufezzt/p/5413902.html