hdu 3627 Giant For

线段树,维护每个区间的maxy,查找时用二分。

/*Accepted    3627    1203MS    6848K    2698 B    C++*/

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;



const int MAXN = 200010;

struct TPoint{

    int x, y, flag;

}pre[MAXN], ans[MAXN], s;



char op[10];

int n, m;



struct Segtree

{

    int l, r, maxy;

}tree[MAXN << 2];



bool cmp(TPoint a, TPoint b)

{

    return a.x < b.x || ( a.x == b.x && a.y < b.y);

}



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

{

    tree[rt].l = l, tree[rt].r = r, tree[rt].maxy = -1;

    if( l == r) return;

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

    build( rt << 1, l, m);

    build( rt << 1 | 1, m + 1, r);

}



int BS( TPoint nd, int l, int r)

{

    while( l <= r){

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

        if( nd.x == ans[m].x && nd.y == ans[m].y) return m;

        if( nd.x < ans[m].x || nd.x == ans[m].x && nd.y < ans[m].y)

            r = m - 1;

        else l = m + 1;

    }

    return -1;

}



void update( int rt, int l, int flag)

{

    if( tree[rt].l == l && tree[rt].r == l)

    {

        if( 1 == flag)

            tree[rt].maxy = ans[l].y;

        if( 2 == flag)

            tree[rt].maxy = -1;

        return;

    }

    int m = (tree[rt].l + tree[rt].r) >> 1;

    if(l <= m) update( rt << 1, l, flag);

    else update( rt << 1 | 1, l, flag);

    tree[rt].maxy = max( tree[rt << 1].maxy, tree[rt << 1 | 1].maxy);

}



void query(int rt, TPoint nd)

{

    if(tree[rt].maxy <= nd.y) return;

    if(ans[tree[rt].r].x <= nd.x) return;

    if( tree[rt].l == tree[rt].r){

        s = ans[tree[rt].l]; return;

    }

    query(rt << 1, nd);

    if(s.x == -1) query(rt << 1 | 1, nd);

}



void prepare()

{

    int i;

    for( i = 1, m = 0; i <= n; i ++)

    {

        scanf( "%s%d%d", op, &pre[i].x, &pre[i].y);

        if('a' == op[0]) {

            pre[i].flag = 1;

            ans[++ m] = pre[i];

        }

        else if( 'r' == op[0]) pre[i].flag = 2;

        else pre[i].flag = 3;

    }

    sort( ans + 1, ans + m + 1, cmp);

    build( 1, 1, m);

}



void operation()

{

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

    {

        int cnt = BS(pre[i], 1, m);

        if( 3 == pre[i].flag)

        {

            s.x = s.y = -1;

            query( 1, pre[i]);

            if( s.x == -1) printf( "-1\n");

            else printf( "%d %d\n", s.x, s.y);

        }

        else{

            update( 1, cnt, pre[i].flag);

        }

    }

}



int main()

{

    int cas = 0;

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

    {

        if( cas ++) printf( "\n");

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

        prepare();

        operation();

    }

    return 0;

}

你可能感兴趣的:(ant)