標籤:efi algorithm isp 分塊 ace == struct hid sort
Beautiful Girl
題意
給定一個長度為 n 的序列 a[1], a[2], ..., a[n] .
m 組詢問 (l, r, K) , 求區間 [l, r] 去除重複的數之後的第 K 小.
n, m <= 100000 .
分析
莫隊演算法 + 範圍分塊.
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 9 inline int rd(void) {10 int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1;11 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f;12 }13 14 const int N = 100005;15 16 int n, a[N], Hash[N], tot;17 18 int m, c, ans[N];19 struct Qry {20 int l, r, K, id;21 friend inline bool operator < (Qry A, Qry B) {22 int ownA = (A.l+c-1)/c, ownB = (B.l+c-1)/c;23 return ownA != ownB ? ownA < ownB : A.r < B.r;24 }25 }qs[N];26 int cnt[N], siz[N];27 28 inline void Add(int x) {29 x = a[x];30 cnt[x]++;31 if (cnt[x] == 1) siz[(x+c-1)/c]++;32 }33 inline void Era(int x) {34 x = a[x];35 cnt[x]--;36 if (!cnt[x]) siz[(x+c-1)/c]--;37 }38 inline int Query(int K) {39 for (int b = 1; ; b++)40 if (siz[b] < K) K -= siz[b];41 else {42 for (int i = (b-1)*c+1; i <= b*c; i++) {43 if (cnt[i] > 0) K--;44 if (!K) return Hash[i];45 }46 }47 }48 49 int main(void) {50 #ifndef ONLINE_JUDGE51 freopen("xsy1640.in", "r", stdin);52 #endif53 54 n = rd(), m = rd();55 F(i, 1, n) a[i] = rd();56 57 F(i, 1, n) Hash[++tot] = a[i];58 sort(Hash+1, Hash+tot+1);59 tot = unique(Hash+1, Hash+tot+1)-Hash-1;60 F(i, 1, n) a[i] = lower_bound(Hash+1, Hash+tot+1, a[i]) - Hash;61 62 c = (int)sqrt(n);63 F(i, 1, m) {64 int l = rd(), r = rd(), K = rd();65 qs[i] = (Qry){l, r, K, i};66 }67 sort(qs+1, qs+m+1);68 69 int mL = 1, mR = 0;70 F(i, 1, m) {71 while (mR < qs[i].r)72 Add(++mR);73 while (mL > qs[i].l)74 Add(--mL);75 while (mR > qs[i].r)76 Era(mR--);77 while (mL < qs[i].l)78 Era(mL++);79 ans[qs[i].id] = Query(qs[i].K);80 }81 F(i, 1, m) printf("%d\n", ans[i]);82 83 return 0;84 }View Code
莫隊演算法