zoukankan      html  css  js  c++  java
  • fzu 1962 树状数组 OR 线段树

    优雅的树状数组!人们发明了复杂度为logn的求解第k小的方法,常数小且代码量小,实在是用来求解本类题目的最佳方法,可惜的是我的Treap超时了......

    树状数组:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 const int N = 500001;
     7 int c[N];
     8 int n, m, maxn;
     9 
    10 int lb( int i )
    11 {
    12     return i & -i;
    13 }
    14 
    15 void update( int i, int v )
    16 {
    17     while ( i <= n )
    18     {
    19         c[i] += v;
    20         i += lb(i);
    21     }
    22 }
    23 
    24 int sum( int i )
    25 {
    26     int ans = 0;
    27     while ( i )
    28     {
    29         ans += c[i];
    30         i -= lb(i);
    31     }
    32     return ans;
    33 }
    34 
    35 int kth( int k )
    36 {
    37     int ans = 0, cnt = 0;
    38     for ( int i = 20; i >= 0; i-- )
    39     {
    40         ans += ( 1 << i );
    41         if ( ans >= maxn || cnt + c[ans] >= k )
    42         {
    43             ans -= ( 1 << i );
    44         }
    45         else
    46         {
    47             cnt += c[ans];
    48         }
    49     }
    50     return ans + 1;
    51 }
    52 
    53 int main ()
    54 {
    55     while ( scanf("%d%d", &n, &m) != EOF )
    56     {
    57         memset( c, 0, sizeof(c) );
    58         for ( int i = 1; i <= n; i++ )
    59         {
    60             update( i, 1 );
    61         }
    62         maxn = n;
    63         while ( m-- )
    64         {
    65             char op[2];
    66             int num;
    67             scanf("%s%d", op, &num);
    68             if ( op[0] == 'L' )
    69             {
    70                 int kk = kth(num);
    71                 update( kk, -1 );
    72             }
    73             else if ( op[0] == 'R' )
    74             {
    75                 if ( sum(num) == sum( num - 1 ) )
    76                 {
    77                     update( num, 1 );
    78                 }
    79             }
    80             else if ( op[0] == 'Q' )
    81             {
    82                 int kk = kth(num);
    83                 printf("%d
    ", kk);
    84             }
    85         }
    86     }
    87     return 0;
    88 }

    线段树当然也可以做:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 const int N = 500001;
     7 int n, m;
     8 
     9 struct Node 
    10 {
    11     int l, r, sum;
    12 } node[N << 2];
    13 
    14 void pushup( int i )
    15 {
    16     node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
    17 }
    18 
    19 void build( int i, int l, int r )
    20 {
    21     node[i].l = l, node[i].r = r, node[i].sum = node[i].r - node[i].l + 1;
    22     if ( l == r ) return ;
    23     int mid = ( l + r ) >> 1;    
    24     build( i << 1, l, mid );
    25     build( i << 1 | 1, mid + 1, r );
    26 }
    27 
    28 void update( int i, int pos, int val )
    29 {
    30     if ( node[i].l == pos && node[i].r == pos )
    31     {
    32         node[i].sum = val;
    33         return ;
    34     }
    35     int mid = ( node[i].l + node[i].r ) >> 1;
    36     if ( pos <= mid )
    37     {
    38         update( i << 1, pos, val );
    39     }
    40     else
    41     {
    42         update( i << 1 | 1, pos, val );
    43     }
    44     pushup(i);
    45 }
    46 
    47 int query( int i, int v )
    48 {
    49     if ( node[i].l == node[i].r ) return node[i].l;
    50     if ( node[i << 1].sum >= v ) return query( i << 1, v );
    51     return query( i << 1 | 1, v - node[i << 1].sum );
    52 }
    53 
    54 int main ()
    55 {
    56     while ( scanf("%d%d", &n, &m) != EOF )
    57     {
    58         build( 1, 1, n );
    59         scanf("%d", &m);
    60         while ( m-- )
    61         {
    62             char op[2];
    63             int x;
    64             scanf("%s %d", op, &x);
    65             if ( op[0] == 'L' )
    66             {
    67                 int kk = query( 1, x );
    68                 update( 1, kk, 0 );
    69             }
    70             else if ( op[0] == 'R' )
    71             {
    72                 update( 1, x, 1 );
    73             }
    74             else if ( op[0] == 'Q' )
    75             {
    76                 int kk = query( 1, x );
    77                 printf("%d
    ", kk);
    78             }
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    ExtJS小技巧
    Oracle 表的行数、表占用空间大小,列的非空行数、列占用空间大小 查询
    NPM 私服
    IDEA 不编译java以外的文件
    SQL 引号中的问号在PrepareStatement 中不被看作是占位符
    Chrome 浏览器自动填表呈现淡黄色解决
    批量删除Maven 仓库未下载成功.lastupdate 的文件
    Oracle 11g 监听很慢,由于监听日志文件太大引起的问题(Windows 下)
    Hibernate 自动更新表出错 建表或添加列,提示标识符无效
    Hibernate 自动更新表出错 More than one table found in namespace
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4740404.html
Copyright © 2011-2022 走看看