HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )

线段树成段更新+区间最值。

注意某人的乘车区间是[a, b-1],因为他在b站就下车了。

#include <cstdio>

#include <cstring>

#include <cstdlib>

#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



using namespace std;



const int MAXN = 1000100;



struct node

{

    int l, r;

};



node D[MAXN];

int limit, Q;

int maxi[ MAXN << 2 ];

int lazy[ MAXN << 2 ];

int N;



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

{

    maxi[rt] = lazy[rt] = 0;

    if ( l == r ) return;

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

    build( lson );

    build( rson );

    return;

}



void PushUp( int rt )

{

    maxi[rt] = max( maxi[lc], maxi[rc] );

    return;

}



void PushDown( int rt )

{

    if ( lazy[rt] )

    {

        lazy[lc] += lazy[rt];

        lazy[rc] += lazy[rt];

        maxi[lc] += lazy[rt];

        maxi[rc] += lazy[rt];

        lazy[rt] = 0;

    }

    return;

}



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

{

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

    {

        lazy[rt] += 1;

        maxi[rt] += 1;

        return;

    }

    PushDown( rt );

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

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

    if ( R > m )  update( L, R, rson );

    PushUp( rt );

    return;

}



int query( int L, int R, int l, int r, int rt )

{

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

    {

        return maxi[rt];

    }

    PushDown( rt );

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



    int res = -10;

    if ( L <= m ) res = max( res, query( L, R, lson ) );

    if ( R > m )  res = max( res, query( L, R, rson ) );

    PushUp( rt );

    return res;

}



int main()

{

    int T, cas = 0;

    scanf( "%d", &T );

    while ( T-- )

    {

        scanf( "%d%d", &limit, &Q );

        N = 0;

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

        {

            int u, v;

            scanf( "%d%d", &u, &v );

            N = max( N, v );

            --v;

            D[i].l = u, D[i].r = v;

        }



        build( 1, N, 1 );

        printf( "Case %d:\n", ++cas );

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

        {

            int ans = query( D[i].l, D[i].r, 1, N, 1 );

            if ( ans < limit )

            {

                printf( "%d ", i + 1 );

                update( D[i].l, D[i].r, 1, N, 1 );

            }

        }

        puts("\n");

    }

    return 0;

}

 

你可能感兴趣的:(HDU)