poj 3368 线段树

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

每个结点维护左右端点的值和出现次数(长度)以及该区间的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 len, llen, rlen;
13     friend Node operator + ( const Node & ln, const Node & rn )
14     {
15         Node res;
16         res.l = ln.l;
17         res.r = rn.r;
18         if ( a[ln.l] == a[rn.l] )
19         {
20             res.llen = ln.llen + rn.llen;
21         }
22         else
23         {
24             res.llen = ln.llen;
25         }
26         if ( a[ln.r] == a[rn.r] )
27         {
28             res.rlen = ln.rlen + rn.rlen;
29         }
30         else
31         {
32             res.rlen = rn.rlen;
33         }
34         res.len = max( ln.len, rn.len );
35         if ( a[ln.r] == a[rn.l] )
36         {
37             res.len = max( res.len, ln.rlen + rn.llen );
38         }
39         return res;
40     }
41 } node[N << 2];
42 
43 void build( int i, int l, int r )
44 {
45     if ( l == r )
46     {
47         node[i].l = node[i].r = l;
48         node[i].len = node[i].llen = node[i].rlen = 1;
49         return ;
50     }
51     int mid = ( l + r ) >> 1;
52     build( i << 1, l, mid );
53     build( i << 1 | 1, mid + 1, r );
54     node[i] = node[i << 1] + node[i << 1 | 1];
55 }
56 
57 Node query( int i, int l, int r )
58 {
59     if ( node[i].l == l && node[i].r == r )
60     {
61         return node[i];
62     }
63     int mid = ( node[i].l + node[i].r ) >> 1;
64     if ( r <= mid )
65     {
66         return query( i << 1, l, r );
67     }
68     else if ( l > mid )
69     {
70         return query( i << 1 | 1, l, r );
71     }
72     else
73     {
74         return query( i << 1, l, mid ) + query( i << 1 | 1, mid + 1, r );
75     }
76 }
77 
78 int main ()
79 {
80     int n, m;
81     while ( scanf("%d", &n), n )
82     {
83         scanf("%d", &m);
84         for ( int i = 1; i <= n; i++ )
85         {
86             scanf("%d", a + i);
87         }
88         build( 1, 1, n );
89         while ( m-- )
90         {
91             int a, b;
92             scanf("%d%d", &a, &b);
93             Node ans = query( 1, a, b );
94             printf("%d\n", ans.len);
95         }
96     }
97     return 0;
98 }

 

posted @ 2015-08-09 15:39  hxy_has_been_used  阅读(131)  评论(0编辑  收藏  举报