zoukankan      html  css  js  c++  java
  • 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
    ", ans.len);
    95         }
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    线段树节点到底开多大
    HDU4901 The Romantic Hero DP
    VIM 配置文件可执行命令
    codeforces159D
    codeforces416B
    codeforces165C
    codeforces332B
    Node.js权威指南 (9)
    iOS-android-windowsphone等移动终端平台开发流程图
    前端面试题细节问题
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4715247.html
Copyright © 2011-2022 走看看