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