1013 小石的妹子 树状数组 排序 贪心

 链接:https://ac.nowcoder.com/acm/contest/26896/1013
来源:牛客网

题目描述

小石有 n 个妹子,每个妹子都有一个细心程度 aia_iai 和一个热心程度 bib_ibi
小石想给她们一个重要程度 tit_iti(重要程度为 1 表示最重要,重要程度越小表示越重要)。
如果一个妹子 i 的细心程度和热心程度都比妹子 j 大,那么妹子 i 的重要程度要大于妹子 j 的重要程度,即妹子 i 比妹子 j 重要。
流程如下:
每次从所有没有重要程度的妹子中,找到若干妹子。对于这些妹子的任意一个,需要保证没有其他妹子比她更重要。然后把她们的重要程度标为 1 。下一次再从剩下没有重要程度的妹子中找到若干妹子,依然符合上述条件,然后把她们的重要程度标为 2,……,重复直到所有妹子都有自己的重要程度。
由于妹子太多,小石忙不过来,请你帮帮他。

输入描述:

第一行输入一个正整数 n,表示妹子的数量。
接下来 n 行,每行两个正整数 ai,bia_i,b_iai,bi,描述每个妹子的细心程度和热心程度。 
保证所有的 aia_iai 两两不等,所有的 bib_ibi 两两不等。 

输出描述:

共 n 行,第 i 行输出一个正整数 tit_iti 表示第 i 个妹子的重要程度。
示例1

输入

复制
5
1 4
2 2
3 3
4 1
5 5

输出

复制
2
3
2
2
1

说明

第一轮取第 5 个妹子(5 5),因为没有其他妹子比她重要,标记为 1;

第二轮取编号为 1,3,4 的妹子,因为对于其中的任意一个妹子,都没有其他妹子比她们重要,标记为 2;

第三轮把编号为 2 的妹子标记为 3 。

备注:

1≤n≤105,1≤ai,bi≤1091 \leq n \leq 10^5,1 \leq a_i,b_i \leq 10^91n105,1ai,bi109

分析

题意:俩值都大,才能排在别人前面,否则必须排在别人后面

贪心地想,应该先把两个值都是最大的排好了,给其它的两个值都比它小的垫脚,所以后放的等级总是要比先放的所有两个值都比它大的等级+1

先按照第一个关键字从大到小排序,然后标记它们的值的顺序,然后再按照第二个关键字从大到小排序,并挨个往树状数组里按照它们的第一关键字的顺序以及当前的等级放,树状数组的权值为满足条件的等级的最大值,查询的时候也直接按照它的第一关键字排名查询,看看前面比它权值大的最大等级是多少(因为第二关键字已经排好序了)。

 

//-------------------------代码----------------------------

//#define int ll
const int N = 1e5+10;
int n,m;

struct node {
    int a,b,v,id;
} no[N];

bool cmp1(node &a,node &b) {
    return a.a > b.a;
}

bool cmp2(node &a,node &b) {
    return a.b > b.b;
}

int tr[N];

void add(int x,int v) {
    for(int i = x;i<=N;i+=lowbit(i)) {
        tr[i] = max(tr[i],v);
    }
}

int query(int x) {
    int res = 0;
    for(int i = x;i;i-=lowbit(i)) {
        res = max(res,tr[i]);
    }
    return res;
}
int ans[N];

void solve()
{
//    cin>>n>>m;
    cin>>n;
    fo(i,1,n) cin>>no[i].a>>no[i].b,no[i].id = i;
    
    sort(no+1,no+1+n,cmp1);
    
    fo(i,1,n) no[i].v = i;
    
    sort(no+1,no+1+n,cmp2);
    fo(i,1,n) {
        ans[no[i].id] = query(no[i].v)+1;
        add(no[i].v,ans[no[i].id]);
    }
    
    fo(i,1,n) {
        cout<<ans[i]<<'\n';
    }
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-09 17:54  er007  阅读(32)  评论(0)    收藏  举报