BZOJ 1878 [SDOI2009]HH的項鏈 (主席樹 或 莫隊算法)
阿新 • • 發佈:2017-09-02
pro can while str hh的項鏈 -c tmp online highlight
題目鏈接 HH的項鏈
這道題可以直接上主席樹的模板
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 5e4 + 10; const int M = 3e6 + 10; int n, tot, q, a[N]; int T[M], lson[M], rson[M], val[M]; int nxt[N], b[N]; int m; int build(int l, int r){ int rt = tot++; val[rt] = 0; int m = (l + r) >> 1; if(l != r){ lson[rt] = build(l, m); rson[rt] = build(m + 1, r); } return rt; } int update(int rt, int pos, int v){ int newrt = tot++, tmp = newrt; int l = 1, r = n; val[newrt] = val[rt] + v; while(l < r) { int m = (l + r) >> 1; if(pos <= m) { lson[newrt] = tot++; rson[newrt] = rson[rt]; newrt = lson[newrt]; rt = lson[rt]; r = m; } else { rson[newrt] = tot++; lson[newrt] = lson[rt]; newrt = rson[newrt]; rt = rson[rt]; l = m + 1; } val[newrt] = val[rt] + v; } return tmp; } int query(int rt, int pos){ int ret = 0; int l = 1, r = n; while(pos > l){ int m = (l + r) >> 1; if (pos <= m){ ret += val[rson[rt]]; rt = lson[rt]; r = m; } else{ l = m + 1; rt = rson[rt]; } } return ret + val[rt]; } int ask(int l, int r){ return query(T[r], l); } void init(){ tot = 0; memset(nxt, -1, sizeof(nxt)); rep(i, 1, n) b[i - 1] = a[i]; sort(b, b + n); int cnt = unique(b, b + n) - b; T[0] = build(1, n); rep(i, 1, n){ int id = lower_bound(b, b + cnt, a[i]) - b; if(nxt[id] == -1) T[i] = update(T[i - 1], i, 1); else{ int t = update(T[i - 1], nxt[id], -1); T[i] = update(t, i, 1); } nxt[id] = i; } } int main(){ scanf("%d", &n); rep(i, 1, n) scanf("%d", a + i); init(); scanf("%d", &m); while (m--){ int x, y; scanf("%d%d", &x, &y); printf("%d\n", ask(x, y)); } return 0; }
當然用莫隊算法也是可以做的
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 2e5 + 10; int belong[N]; int a[N], b[N], c[N], ans[N]; int n, m, l, r, cnt, BS; int now = 0; struct node{ int l, r, id; friend bool operator < (const node &a, const node &b){ return belong[a.l] == belong[b.l] ? belong[a.r] < belong[b.r] : belong[a.l] < belong[b.l]; } } q[N]; int main(){ scanf("%d", &n); BS = (int)sqrt(n + 0.5); rep(i, 1, n) scanf("%d", a + i), b[i] = a[i]; sort(b + 1, b + n + 1); cnt = unique(b + 1, b + n + 1) - b - 1; rep(i, 1, n) a[i] = lower_bound(b + 1, b + cnt + 1, a[i]) - b; scanf("%d", &m); rep(i, 1, m){ scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; } rep(i, 1, n) belong[i] = (i - 1) / BS + 1; sort(q + 1, q + m + 1); l = 0, r = 0; rep(i, 1, m){ while (l > q[i].l){ --l; if (c[a[l]] == 0) ++now; ++c[a[l]]; } while (r < q[i].r){ ++r; if (c[a[r]] == 0) ++now; ++c[a[r]]; } while (l < q[i].l){ --c[a[l]]; if (!c[a[l]]) --now; ++l; } while (r > q[i].r){ --c[a[r]]; if (!c[a[r]]) --now; --r; } ans[q[i].id] = now; } rep(i, 1, m) printf("%d\n", ans[i]); return 0; }
BZOJ 1878 [SDOI2009]HH的項鏈 (主席樹 或 莫隊算法)