莫队算法。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int maxn = 50000 + 10; int n, m; int a[maxn],pos[maxn],cnt[1000000+10]; long long ans[200000+10], Ans; int L, R; struct X { int l, r, id; }s[200000+10]; 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 main() { int T; scanf("%d",&T); while (T--) { memset(cnt,0,sizeof cnt); scanf("%d", &n); int sz = sqrt(n); for (int i = 1; i <= n; i++) { pos[i] = i / sz; scanf("%d", &a[i]); } 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++) { cnt[a[i]]++; if(cnt[a[i]]==1) Ans=Ans+(long long)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) { cnt[a[L]]--; if(cnt[a[L]]==0) Ans=Ans-(long long)a[L]; L++; } while (L > s[i].l) { L--; cnt[a[L]]++; if(cnt[a[L]]==1) Ans=Ans+(long long)a[L]; } while (R < s[i].r) { R++; cnt[a[R]]++; if(cnt[a[R]]==1) Ans=Ans+(long long)a[R]; } while (R > s[i].r) { cnt[a[R]]--; if(cnt[a[R]]==0) Ans=Ans-(long long)a[R]; R--; } ans[s[i].id] = Ans; } for (int i = 1; i <= m; i++) printf("%lld ", ans[i]); } return 0; }