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 }
  • 相关阅读:
    接口测试总结
    在 github 上获取源码
    推荐一个css帮助手册的版本 同时提供chm和在线
    由csdn开源项目评选中闹出刷票问题想到投票程序的设计
    由一个园友因为上传漏洞导致网站被攻破而得到的教训
    让 SVN (TortoiseSVN)提交时忽略bin和obj目录
    未能进入中断模式,原因如下:源文件“XXXXXX”不属于正在调试的项目。
    未能加载文件或程序集“XXXXX”或它的某一个依赖项。试图加载格式不正确的程序。
    .Net AppDomain.CurrentDomain.AppendPrivatePath(@"Libs");
    C# Remoting的一个简单例子
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4740404.html
Copyright © 2011-2022 走看看