BZOJ3524: [Poi2014]Couriers(主席樹)
阿新 • • 發佈:2019-01-03
題意
Sol
嚴格眾數只會出現一次,那麼建出主席樹,維護子樹siz,直接在樹上二分即可
#include<bits/stdc++.h> #define LL long long using namespace std; const int MAXN = 2e6 + 10; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, a[MAXN], date[MAXN], rt[MAXN], num; //struct GZYAKIOI { #define MAX (MAXN * 10) int tot, ls[MAX], rs[MAX], siz[MAX]; void insert(int &rt, int pre, int l, int r, int v) { rt = ++tot; ls[rt] = ls[pre]; rs[rt] = rs[pre]; siz[rt] = siz[pre] + 1; if(l == r) return ; int mid = l + r >> 1; if(v <= mid) insert(ls[rt], ls[pre], l, mid, v); else insert(rs[rt], rs[pre], mid + 1, r, v); } int Query(int pre, int rt, int l, int r, int v) { if(l == r) return (siz[rt] - siz[pre] > v ? date[l] : 0); int mid = l + r >> 1; if(siz[ls[rt]] - siz[ls[pre]] > v) return Query(ls[pre], ls[rt], l, mid, v); else return Query(rs[pre], rs[rt], mid + 1, r, v); } //}T; signed main() { N = read(); M = read(); for(int i = 1; i <= N; i++) a[i] = date[i] = read(); sort(date + 1, date + N + 1); num = unique(date + 1, date + N + 1) - date - 1; for(int i = 1; i <= N; i++) a[i] = lower_bound(date + 1, date + num + 1, a[i]) - date, insert(rt[i], rt[i - 1], 1, num, a[i]); while(M--) { int l = read(), r = read(); printf("%d\n", Query(rt[l - 1], rt[r], 1, num, (r - l + 1) / 2)); } return 0; } /* 7 5 1 1 3 2 3 4 3 6 6 1 3 1 4 3 7 1 7 */