码迷,mamicode.com
首页 > 编程语言 > 详细

莫队算法

时间:2017-09-19 23:11:21      阅读:272      评论:0      收藏:0      [点我收藏+]

标签: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_JUDGE
51         freopen("xsy1640.in", "r", stdin);
52     #endif
53     
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

 

莫队算法

标签:efi   algorithm   isp   分块   ace   ==   struct   hid   sort   

原文地址:http://www.cnblogs.com/Sdchr/p/7554111.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!