ZOJ 3606 Lazy Salesgirl ( 线段树 + 思路 )

卖切糕的小女孩

http://www.cnblogs.com/wuyiqi/archive/2012/04/28/2474672.html

 

#include <cstdio>

#include <cstring>

#include <algorithm>



#define lson l, m, rt << 1

#define rson m+1, r, rt << 1 | 1

#define lc rt << 1

#define rc rt << 1 | 1

#define LL long long int



using namespace std;



const int MAXN = 100100;

const double INF = 1e100;

const double eps = 1e-9;



struct node

{

    int p;

    int t;

    int id;

};



int N;

int cnt[MAXN << 2];

LL sum[3][MAXN << 2];

node D1[MAXN], D2[MAXN];



bool cmp( const node& a, const node& b )

{

    return a.t < b.t;

}



void build( int l, int r, int rt )

{

    cnt[rt]=0;

    for ( int i = 0; i < 3; ++i ) sum[i][rt] = 0;

    if ( l == r ) return;

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

    build( lson );

    build( rson );

    return;

}



void PushUp( int rt )

{

    cnt[rt] = cnt[lc] + cnt[rc];

    for ( int i = 0; i < 3; ++i )

        sum[i][rt] = sum[i][lc] + sum[ (i+cnt[lc])%3 ][rc];

    return;

}



void update( int L, int l, int r, int rt )

{

    if ( l == r && L == l )

    {

        ++cnt[rt];

        for ( int i = 0; i < 3; ++i )

            sum[i][rt] += (LL)D1[L].p * (i + 1);

        return;

    }



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

    if ( L <= m ) update( L, lson );

    else update( L, rson );

    PushUp( rt );

    return;

}



void init()

{

    scanf( "%d", &N );

    build( 1, N, 1 );

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

        scanf( "%d", &D1[i].p );

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

        scanf( "%d", &D1[i].t );



    sort( D1 + 1, D1 + N + 1, cmp );



    D2[0].t = 0;

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

    {

        D2[i].id = i;

        D2[i].t = D1[i].t - D1[i - 1].t;

    }

    sort( D2 + 1, D2 + N + 1, cmp );

    return;

}



void solved()

{

    double minW;

    double maxAve = 0.0;

    int i = 1, j = 1;

    while ( i <= N )

    {

        while ( j <= N && D2[i].t == D2[j].t )

        {

            update( D2[j].id, 1, N, 1 );

            ++j;

        }



        double tmpW = (double)D2[i].t;

        double tmpA = (double)sum[0][1]/cnt[1];

        //printf( "tmp: %f %f\n", tmpW, tmpA );



        if ( tmpA > maxAve )

        {

            maxAve = tmpA;

            minW = tmpW;

        }

        else if ( tmpA == maxAve )

        {

            if ( minW > tmpW )

                minW = tmpW;

        }

        i = j;

    }

    printf( "%.6f %.6f\n", minW, maxAve );

    return;

}



int main()

{

    int T;

    scanf( "%d", &T );

    while (T--)

    {

        init();

        solved();

    }

    return 0;

}

 

你可能感兴趣的:(lazy)