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

poj 3368 线段树

时间:2015-08-09 16:50:14      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:

这道题是要查询某个区间内数字出现的最大次数,序列不降,可以用线段树来做。

每个结点维护左右端点的值和出现次数(长度)以及该区间的Frequent values,然后向上合并即可。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 100001;
 7 int a[N];
 8 
 9 struct Node 
10 {
11     int l, r;
12     int lval, rval;
13     int len, llen, rlen;
14     friend Node operator + ( const Node & ln, const Node & rn )
15     {
16         Node res;
17         res.l = ln.l;
18         res.r = rn.r;
19         res.lval = ln.lval;
20         res.rval = rn.rval;
21         res.llen = ln.llen;
22         if ( ln.lval == ln.rval && ln.rval == rn.lval )
23         {
24             res.llen += rn.llen;
25         }
26         res.rlen = rn.rlen;
27         if ( ln.rval == rn.lval && rn.lval == rn.rval )
28         {
29             res.rlen += ln.rlen;
30         }
31         res.len = max( ln.len, rn.len );
32         if ( ln.rval == rn.lval )
33         {
34             res.len = max( res.len, ln.rlen + rn.llen );
35         } 
36         return res;
37     }
38 } node[N << 2];
39 
40 void build( int i, int l, int r )
41 {
42     if ( l == r )
43     {
44         node[i].l = node[i].r = l;
45         node[i].lval = node[i].rval = a[l];
46         node[i].len = node[i].llen = node[i].rlen = 1;
47         return ;
48     }
49     int mid = ( l + r ) >> 1;
50     build( i << 1, l, mid );
51     build( i << 1 | 1, mid + 1, r );
52     node[i] = node[i << 1] + node[i << 1 | 1];
53 }
54 
55 Node query( int i, int l, int r )
56 {
57     if ( node[i].l == l && node[i].r == r )
58     {
59         return node[i];
60     }
61     int mid = ( node[i].l + node[i].r ) >> 1;
62     if ( r <= mid )
63     {
64         return query( i << 1, l, r );
65     }
66     else if ( l > mid )
67     {
68         return query( i << 1 | 1, l, r );
69     }
70     else
71     {
72         return query( i << 1, l, mid ) + query( i << 1 | 1, mid + 1, r );
73     }
74 }
75 
76 int main ()
77 {
78     int n, m;
79     while ( scanf("%d", &n), n )
80     {
81         scanf("%d", &m);
82         for ( int i = 1; i <= n; i++ )
83         {
84             scanf("%d", a + i);
85         }
86         build( 1, 1, n );
87         while ( m-- )
88         {
89             int a, b;
90             scanf("%d%d", &a, &b);
91             Node ans = query( 1, a, b );
92             printf("%d\n", ans.len);
93         }
94     }
95     return 0;
96 }

 

poj 3368 线段树

标签:

原文地址:http://www.cnblogs.com/huoxiayu/p/4715247.html

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