随笔 - 11, 文章 - 0, 评论 - 12, 引用 - 0
数据加载中……

Giant For (2010天津网赛 1007)

题目大意:
        输入给出三种操作:
              1、add     x     y
              2、remove   x   y
              3、find  x   y
      每次find的时候找到一个组合(X0,Y0) (X0>x,Y0>y且X0,Y0没有被移除)。
N<=200000 比较大,不可能每次都排序, 这时线段数发挥了它强大的威力。
思路:
      离线操作,先离散化,再按原来的顺序进行每一步操作,每一个区间保存本区间内y的最大值,插入和移除的时候都要及时更新。
注意离散化的时候add  与 remove同一个点的时候,不能离散为两个点。也就是离散的对象只能是add和find的坐标。就因为这个比赛的时候不停的WA。
#include<iostream>
#include
<queue>
#include
<map>
#include
<cmath>
#include
<cstdio>
#include
<algorithm>
#include
<string>
using namespace std;

const int N = 200005;

struct node{
    
char s[10];
    
int x,y;
    
int id;
    
const bool operator<(const node &b)const{
        
return x<b.x||x==b.x&&y<b.y;
    }

}
dd[N],tt[N];

struct cod{
    
int l,r;
    
int num;
    
int cal;
}
tree[3*N];

int n,m,flag[N],x,y;

bool cmp(const node a,const node b){
    
return a.id<b.id;
}


void build(int l,int r,int dep)
{
    tree[dep].l
=l;
    tree[dep].r
=r;
    tree[dep].num
=0;
    tree[dep].cal
=0;
    
if(l<r){
        
int mid=(l+r)/2;
        build(l,mid,
2*dep);
        build(mid
+1,r,2*dep+1);
    }

}


void add(int l,int r,int val,int dep)
{
    
if(l<=tree[dep].l&&tree[dep].r<=r)
        tree[dep].cal
=val;
        tree[dep].num
=dd[val].y;
        
return;
    }

    
int mid=(tree[dep].l+tree[dep].r)/2;

    
if(mid>=l) add(l,r,val,2*dep);
    
if(mid<r) add(l,r,val,2*dep+1);

    tree[dep].num
=max(tree[2*dep].num,tree[2*dep+1].num);
}


void remove(int l,int r,int val,int dep)
{
    
if(l<=tree[dep].l&&tree[dep].r<=r)
        tree[dep].num
=0;
        tree[dep].cal
=0;
        
return;
    }


    
int mid=(tree[dep].l+tree[dep].r)/2;

    
if(mid>=l) remove(l,r,val,2*dep);
    
if(mid<r) remove(l,r,val,2*dep+1);

    tree[dep].num
=max(tree[2*dep].num,tree[2*dep+1].num);

}

bool find(int l,int r,int val,int dep)
{
    
int mx=tree[dep].num;
    
if(mx<=dd[val].y) return false;

    
if(tree[dep].l==tree[dep].r){
        
int id=tree[dep].cal;
        
if(id!=0){
            
if(dd[id].x>dd[val].x&&dd[id].y>dd[val].y)
                x
=dd[id].x,y=dd[id].y;
                
return true;
            }

        }

        
return false;
    }

    
int mid=(tree[dep].l+tree[dep].r)/2;
    
if(mid>=l){
        
if(find(l,r,val,2*dep)) return true;
    }

    
if(mid<r){
        
if(find(l,r,val,2*dep+1)) return true;
    }

    
return false;
}

void solve()
{
    
int cnt=1;
    
while(scanf("%d",&n)&&n){
        
        build(
1,n,1);
        m
=0;
        
for(int i=1;i<=n;i++){
            scanf(
"%s%d%d",dd[i].s,&dd[i].x,&dd[i].y);
            dd[i].id
=i;
        }

        sort(dd
+1,dd+n+1);
        
for(int i=1;i<=n;i++){
            
if(i>1){
                
if(dd[i].x==dd[i-1].x&&dd[i].y==dd[i-1].y){
                    flag[dd[i].id]
=flag[dd[i-1].id];
                }

                
else flag[dd[i].id]=++m;
            }

            
else flag[dd[i].id]=++m;
        }

        sort(dd
+1,dd+n+1,cmp);
        
        
if(cnt>1) printf("\n");
        printf(
"Case %d:\n",cnt++);
        
for(int i=1;i<=n;i++){
            
if('a'==dd[i].s[0]){
                add(flag[i],flag[i],i,
1);
            }

            
else if('r'==dd[i].s[0]){
                remove(flag[i],flag[i],i,
1);
            }

            
else{
                x
=-N,y=-N;
                find(flag[i],m,i,
1);
                
if(x!=-N) 
                    printf(
"%d %d\n",x,y);
                
else printf("-1\n");
            }

        }

    }

}


int main()
{
    solve();
    
return 0;
}

posted on 2010-09-13 14:56 acleast 阅读(198) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理