莫队基础
//http://www.spoj.com/problems/DQUERY/ #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; const int MAXN = 30009; const int MAXM = 1000009; const int MAXQ = 200009; int n, q, sum, B, a[MAXN], ans[MAXQ], cnt[MAXM]; struct Lu { int lef, rig, id; bool operator < (const Lu &p)const { if ((lef - 1) / B == (p.lef - 1)/B) return rig < p.rig; return (lef - 1) / B < (p.lef - 1) / B; } } L[MAXQ]; void add(int x) { ++cnt[a[x]]; if (cnt[a[x]] == 1) ++sum; } void remove(int x) { --cnt[a[x]]; if (cnt[a[x]] == 0) --sum; } int main() { memset(cnt, 0, sizeof(cnt)); scanf("%d", &n); B = sqrt(n); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); scanf("%d", &q); for (int i = 1; i <= q; ++i) { scanf("%d %d", &L[i].lef, &L[i].rig); L[i].id = i; } sort(L + 1, L + 1 + q); sum = 1; int LL = 1, RR = 1; cnt[a[1]]=1; for (int i = 1; i <= q; ++i) { while (LL < L[i].lef) remove(LL++); while (LL > L[i].lef) add(--LL); while (RR > L[i].rig) remove(RR--); while (RR < L[i].rig) add(++RR); ans[L[i].id] = sum; } for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]); return 0; } //带修改莫队 // B可设为 sqrt(n) * 10 或其他值。 http://www.lydsy.com/JudgeOnline/problem.php?id=2120 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAXN = 10009; const int MAXM = 1000009; int n, q, sum, B, a[MAXN], b[MAXN], cnt[MAXM], change[MAXN][3], ans[MAXN]; int LL = 1, RR = 1, TT = 0; struct Lu { int lef, rig, tim, id; bool operator < (const Lu &p)const { if ((lef - 1 / B == (p.lef - 1) / B)) { if ((rig - 1) / B == (p.rig - 1) / B) return tim < p.tim; return (rig - 1) / B < (p.rig - 1) / B; } return (lef - 1) / B < (p.lef - 1) / B; } } L[MAXN]; inline bool bound(int x) { return x >= LL && x <= RR; } inline void remove(int x) { --cnt[a[x]]; if (cnt[a[x]] == 0) --sum; } inline void add(int x) { ++cnt[a[x]]; if(cnt[a[x]] == 1) ++sum; } inline void update(int x, int y) { if (x >= LL && x <= RR) { --cnt[a[x]]; if (cnt[a[x]] == 0) --sum; if (cnt[y] == 0) ++sum; ++cnt[y]; } a[x] = y; } int main() { scanf("%d %d", &n, &q); B = pow(n, 2 / 3); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); b[i] = a[i]; } char ch[2]; int pp = 0, p = 0; for (int i = 1; i <= q; ++i) { scanf("%s", ch); if (ch[0] == 'Q') { ++p; scanf("%d %d", &L[p].lef, &L[p].rig); L[p].tim = pp; L[p].id = p; } else { ++pp; scanf("%d %d", &change[pp][0], &change[pp][1]); change[pp][2] = b[change[pp][0]]; b[change[pp][0]] = change[pp][1]; } } sort(L + 1, L + 1 + p); memset(cnt, 0, sizeof(cnt)); cnt[a[1]] = 1; sum = 1; for (int i = 1; i <= q - pp; ++i) { while (TT < L[i].tim) { ++TT; update(change[TT][0], change[TT][1]); } while (TT > L[i].tim) { update(change[TT][0], change[TT][2]); --TT; } while (LL < L[i].lef) remove(LL++); while (LL > L[i].lef) add(--LL); while (RR > L[i].rig) remove(RR--); while (RR < L[i].rig) add(++RR); ans[L[i].id] = sum; } for (int i = 1; i <= p; ++i) printf("%d\n", ans[i]); return 0; }