#include<bits/stdc++.h> usingnamespace std; constint N = 1000000 + 5; int n, m, len; int w[N], ans[N]; structQuestion { int id, l, r; #define id(i) q[i].id #define l(i) q[i].l #define r(i) q[i].r } q[N]; int cnt[N]; intread() { char ch = getchar(); int x = 0, f = 1; while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } intget(int x) { return x / len; } boolcmp(const Question &a, const Question &b) { int i = get(a.l), j = get(b.l); if (i != j) return i < j; return a.r < b.r; } voidadd(int x, int &res) { if (!cnt[x]) res++; cnt[x]++; } voiddel(int x, int &res) { cnt[x]--; if (!cnt[x]) res--; } intmain() { n = read(); for (int i = 1; i <= n; ++i) w[i] = read(); m = read(); len = sqrt((double)n * n / m); //len的长度很玄学,会直接影响时间复杂度 for (int i = 0; i < m; ++i) { q[i].id = i; q[i].l = read(); q[i].r = read(); } sort(q, q + m, cmp); for (int k = 0, j = 0, i = 1, res = 0; k < m; ++k) { while (j < r(k)) add(w[++j], res); while (j > r(k)) del(w[j--], res); while (i < l(k)) del(w[i++], res); while (i > l(k)) add(w[--i], res); ans[id(k)] = res; } for (int i = 0; i < m; ++i) printf("%d\n", ans[i]); return0; }
#include<bits/stdc++.h> usingnamespace std; constint N = 100000 + 5; typedeflonglong LL; int n, m, len; int w[N], cnt[N]; LL ans[N]; structQuestion { int id, l, r; #define id(k) q[k].id #define l(k) q[k].l #define r(k) q[k].r } q[N]; vector<int> nums; //离散化用 inlineintread() { char ch = getchar(); int x = 0; while (ch < '0' || ch > '9') ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x; } inlineintget(int x) { return x / len; } boolcmp(Question x, Question y) { int i = get(x.l), j = get(y.l); if (i != j) return i < j; return x.r < y.r; } inlinevoidadd(int x, LL &res) { cnt[x]++; res = max(res, (LL)cnt[x] * nums[x]); } intmain() { n = read(), m = read(); len = sqrt(n);
//离散化 for (int i = 1; i <= n; ++i) w[i] = read(), nums.push_back(w[i]); sort(nums.begin(), nums.end()); nums.erase(unique(nums.begin(), nums.end()), nums.end()); for (int i = 1; i <= n; ++i) w[i] = lower_bound(nums.begin(), nums.end(), w[i]) - nums.begin();
for (int i = 0; i < m; ++i) { int a = read(), b = read(); id(i) = i, l(i) = a, r(i) = b; } sort(q, q + m, cmp);
for (int x = 0; x < m;) { int y = x; while (y < m && get(l(y)) == get(l(x))) //完成后x~y就是同块的 ++y; int right = get(l(x)) * len + len - 1; //本块右端点
//暴力求块内 while (x < y && r(x) < right) { LL res = 0; for (int k = l(x); k <= r(x); ++k) add(w[k], res); ans[id(x)] = res; for (int k = l(x); k <= r(x); ++k) //回复 cnt[w[k]]--;
x++; }
//求跨块 LL res = 0; int j = right, i = right + 1; while (x < y) { while (j < r(x)) //右指针只增不删 add(w[++j], res);
LL b_res = res; //存档 while (i > l(x)) add(w[--i], res);
ans[id(x)] = res;
//回复 while (i < right + 1) cnt[w[i++]]--; res = b_res;
x++; }
memset(cnt, 0, sizeof cnt); //换块,清空 }
for (int i = 0; i < m; ++i) printf("%lld\n", ans[i]);