HDU 4262 Juggler 树状数组

将每个球按输入顺序编号,建立 它第几个被扔掉->编号 的映射关系。

记录当前在手里的球的编号,按扔掉的顺序查找这个球的编号,看看这个球是逆时针转到手里更近还是顺时针转到手里更近,即当前扔掉球的编号与当前手里球的编号之间有几个球。

树状数组C[i]记录编号i的球是否还在。

球是环形排列的,特殊处理一下。

对于扔掉一个球之后下一个落在手里的球的编号,二分判定,找顺时针方向第一个有球的位置

 

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>



#define LL long long int



using namespace std;



const int MAXN = 100100;



int C[MAXN];

int N;

int PosToID[MAXN];

int IDToPos[MAXN];



int lowbit( int x )

{

    return x & ( -x );

}



int query( int x )

{

    if ( !x ) return 0;

    int res = 0;

    while ( x > 0 )

    {

        res += C[x];

        x -= lowbit(x);

    }

    return res;

}



void update( int x, int val )

{

    while ( x <= N )

    {

        C[x] += val;

        x += lowbit(x);

    }

    return;

}



int BiSearch( int l, int r )

{

    int pre = l;

    if ( query(r) - query(l) == 0 )

    {

        r = l;

        l = 1;

        pre = 0;

    }



    int ans = 0;

    while ( l <= r )

    {

        int mid = ( l + r ) >> 1;

        if ( query(mid) - query(pre) > 0 )

        {

            ans = mid;

            r = mid - 1;

        }

        else l = mid + 1;

    }

    return ans;

}



int main()

{

    while ( scanf( "%d", &N ), N )

    {

        memset( C, 0, sizeof(C) );

        for ( int i = 1; i <= N; ++i )

        {

            scanf("%d", &IDToPos[i] );

            PosToID[ IDToPos[i] ] = i;

            update( i, 1 );

        }



        int cur = 1;   //当前手里的

        LL ans = 0;

        for ( int i = 1; i <= N; ++i )

        {

            int id = PosToID[i];



            if ( id < cur )

            {

                int tmp = query(cur) - query(id);

                ans += min( tmp, query(N) - query(cur) + query(id) );

            }

            else if ( id > cur )

            {

                int tmp = query(id) - query(cur);

                ans += min( tmp, query(N) - query(id) + query(cur) );

            }

            update( id, -1 );

            ++ans;

            cur = BiSearch( id, N );

        }

        printf( "%I64d\n", ans );

    }

    return 0;

}

 

你可能感兴趣的:(树状数组)