HDU 4251 The Famous ICPC Team Again

本文介绍了一个基于划分树的数据处理算法实现。通过递归构建划分树并实现特定区间查询的功能,适用于处理大规模数据集中的区间查询问题。代码示例中详细展示了如何通过划分树对整数数组进行排序和查询中间值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个也是一道对划分树的简单的运用:

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
using namespace std;
class Node
{
public:
      int num[100024],val[100024];    
}node[20];
int val[100024];
bool cmp( int a , int b )
{
     return a <= b;
}
void build_tree( int l , int r , int deep )
{
     if( l == r ) return ;
     int mid = ( l + r )>>1;
     int issame = mid - l + 1 ,same = 0;
     for( int i = l ; i <= r ; i ++ )
          if( node[deep].val[i] < val[mid] ) issame --;
    int left = l ,right = mid + 1;
    for( int i = l ; i <= r ; i ++ )
    {
          node[deep].num[i] = node[deep].num[i-1];
          if( node[deep].val[i] > val[mid] )
              node[deep+1].val[right++] = node[deep].val[i];
          else if( node[deep].val[i] < val[mid] )
          {
               node[deep+1].val[left++] = node[deep].val[i];
               node[deep].num[i] ++;
          }
          else
          {
              if( same < issame )
              {
                  same ++;
                  node[deep+1].val[left++] = node[deep].val[i];
                  node[deep].num[i] ++;        
              }    
              else     node[deep+1].val[right++] = node[deep].val[i];
          }            
    }
    build_tree( l , mid , deep + 1 );
    build_tree( mid + 1, r ,deep + 1 ); 
}
int find( int a , int b , int k ,int deep, int l ,int r )
{
    //printf( "l=%d,r=%d,s=%d,t=%d,k=%d,dep=%d\n",l,r,a,b,k,deep);system("pause");
     int mid = ( l + r )>>1;
     if( a == b ) return node[deep].val[a];
     int d = node[deep].num[b] - node[deep].num[a-1];
     int s = node[deep].num[a-1] - node[deep].num[l-1];
     int ss = node[deep].num[b] - node[deep].num[l-1];
     int rx =  a - l  + 1 - s,ry = b - l + 1 - ss;
     if( d >= k )  return find( l + s , l + ss - 1 ,k , deep + 1, l , mid );
     else return find( mid + rx , mid + ry , k - d , deep + 1 , mid + 1 , r );
}
int main(  )
{
    int n,m,Case=1,l,r;
    while( scanf( "%d",&n )==1 )
    {
        for( int i = 1 ; i <= n ; i ++ )
        {
            scanf( "%d",&node[0].val[i] );
            val[i] = node[0].val[i];    
        }    
        sort( val+1, val + n + 1, cmp );
        build_tree( 1 , n  , 0 ); 
//        printf( "sfaf" );
        scanf( "%d",&m );
        printf( "Case %d:\n",Case++ );
        for( int i = 0 ; i < m ; i ++ )
        {
             scanf( "%d %d",&l,&r );
             int k = ( r - l )/2 + 1 ;
             printf( "%d\n",find( l  , r , k, 0 , 1, n  ) );    
        }
    }
    //system( "pause" );
    return 0;
}

 

转载于:https://www.cnblogs.com/bo-tao/archive/2012/07/19/2600025.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值