码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 3524] kur 绝对众数

时间:2017-09-11 15:12:13      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:log   --   oid   string   题意   include   key   etc   n+1   

题意

  给定长度为 n 的序列 A = {a[1], a[2], ..., a[n]} .

  m 次询问, 求区间 [l, r] 的绝对众数.

  n, m <= 100000 .

 

分析

  性质1. 如果存在绝对众数, 那么中位数一定是绝对众数.

  性质2. 不同数两两匹配, 最后剩下来的是绝对众数.

 

  建立可持久化线段树, 根据 性质1 , 找中位数有多少个.

  我们用 性质2 带来的摩尔投票法进行对拍.

 

实现

  一般来说, 如果要找中位数, 都用 n+1 >> 1 , 而不是 n >> 1 , 否则当 n = 1 的时候就gg了.

  

  AC程序:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 6 inline int rd(void) {
 7     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
 8     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f;
 9 }
10 
11 const int N = 500005;
12 const int S = 10000000;
13 
14 int n, m, a[N];
15 int rt[N], tot, Lc[S], Rc[S], cnt[S];
16 
17 #define M ((L+R)>>1)
18 inline int Insert(int x, int L, int R, int pos) {
19     int cur = ++tot; Lc[cur] = Lc[x], Rc[cur] = Rc[x], cnt[cur] = cnt[x] + 1;
20     if (L != R)
21         pos <= M ? Lc[cur] = Insert(Lc[x], L, M, pos) : Rc[cur] = Insert(Rc[x], M+1, R, pos);
22     return cur;
23 }
24 inline int Query(int x, int y, int L, int R, int K, int Siz) {
25     if (L == R) return cnt[y] - cnt[x] > Siz ? L : 0;
26     int Lsz = cnt[Lc[y]] - cnt[Lc[x]];
27     return K <= Lsz ? Query(Lc[x], Lc[y], L, M, K, Siz) : Query(Rc[x], Rc[y], M+1, R, K - Lsz, Siz);
28 }
29 
30 int main(void) {
31     #ifndef ONLINE_JUDGE
32         freopen("kur.in", "r", stdin);
33     #endif
34     
35     n = rd(), m = rd();
36     F(i, 1, n) a[i] = rd();
37     F(i, 1, n) rt[i] = Insert(rt[i-1], 1, n, a[i]);
38     
39     F(i, 1, m) {
40         int l = rd(), r = rd();
41         printf("%d\n", Query(rt[l-1], rt[r], 1, n, (r-l+2)/2, (r-l+1)/2));
42     }
43     
44     return 0;
45 }

 

  对拍程序:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 6 inline int rd(void) {
 7     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
 8     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f;
 9 }
10 
11 const int N = 500005;
12 
13 int n, m, a[N];
14 
15 int Query(int l, int r) {
16     int key = 0, cnt = 0;
17     F(i, l, r) {
18         if (!cnt) key = a[i];
19         if (key == a[i]) cnt++; else cnt--;
20     }
21     cnt = 0;
22     F(i, l, r)
23         cnt += (key == a[i]);
24     return cnt > (r-l+1)/2 ? key : 0;
25 }
26 
27 int main(void) {
28     #ifndef ONLINE_JUDGE
29         freopen("kur.in", "r", stdin);
30     #endif
31     
32     n = rd(), m = rd();
33     F(i, 1, n) a[i] = rd();
34     
35     F(i, 1, m) {
36         int l = rd(), r = rd();
37         printf("%d\n", Query(l, r));
38     }
39     
40     return 0;
41 }

 

[BZOJ 3524] kur 绝对众数

标签:log   --   oid   string   题意   include   key   etc   n+1   

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

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