bzoj 3236 [Ahoi2013]作業 莫隊+樹狀數組
阿新 • • 發佈:2018-08-15
owb \n emp line ahoi2013 uniq str oid 樹狀
題面
題目傳送門
解法
離線詢問,然後莫隊
建2棵權值樹狀數組,一棵為區間有多少個數,另一棵為區間有多少個不同的數
在擴展區間的時候用樹狀數組修改即可
代碼
#include <bits/stdc++.h> #define N 3000010 using namespace std; template <typename node> void chkmax(node &x, node y) {x = max(x, y);} template <typename node> void chkmin(node &x, node y) {x = min(x, y);} template <typename node> void read(node &x) { x = 0; int f = 1; char c = getchar(); while (!isdigit(c)) {if (c == ‘-‘) f = -1; c = getchar();} while (isdigit(c)) x = x * 10 + c - ‘0‘, c = getchar(); x *= f; } int n, m, len, a[N], c[N], col[N], cnt[N], ans[N][2]; struct Node { int l, r, x, y, id; } b[N]; struct BIT { int f[N]; int lowbit(int x) {return x & -x;} void modify(int x, int v) { for (int i = x; i <= len; i += lowbit(i)) f[i] += v; } int query(int x) { int ret = 0; for (int i = x; i; i -= lowbit(i)) ret += f[i]; return ret; } } T1, T2; bool cmp(Node a, Node b) { return col[a.l] == col[b.l] ? a.r < b.r : a.l < b.l; } void update(int x, int v) { cnt[a[x]] += v; T1.modify(a[x], v); if (v == 1) if (cnt[a[x]] == 1) T2.modify(a[x], 1); if (v == -1) if (!cnt[a[x]]) T2.modify(a[x], -1); } main() { read(n), read(m); len = 0; for (int i = 1; i <= n; i++) read(a[i]), c[++len] = a[i]; int siz = (int)sqrt(n); for (int i = 1; i <= n; i++) col[i] = (i + siz - 1) / siz; for (int i = 1; i <= m; i++) { read(b[i].l), read(b[i].r), read(b[i].x), read(b[i].y), b[i].id = i; c[++len] = b[i].x, c[++len] = b[i].y; } sort(c + 1, c + len + 1); len = unique(c + 1, c + len + 1) - c - 1; map <int, int> h; for (int i = 1; i <= len; i++) h[c[i]] = i; for (int i = 1; i <= n; i++) a[i] = h[a[i]]; for (int i = 1; i <= m; i++) b[i].x = h[b[i].x], b[i].y = h[b[i].y]; sort(b + 1, b + m + 1, cmp); for (int i = 1, l = 1, r = 0; i <= m; i++) { while (r < b[i].r) update(++r, 1); while (r > b[i].r) update(r--, -1); while (l < b[i].l) update(l++, -1); while (l > b[i].l) update(--l, 1); ans[b[i].id][0] = T1.query(b[i].y) - T1.query(b[i].x - 1); ans[b[i].id][1] = T2.query(b[i].y) - T2.query(b[i].x - 1); } for (int i = 1; i <= m; i++) cout << ans[i][0] << ‘ ‘ << ans[i][1] << "\n"; return 0; }
bzoj 3236 [Ahoi2013]作業 莫隊+樹狀數組