• 牛客小白月赛16 F 小石的妹子 (线段树)


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

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

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

    输入描述:

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

    输出描述:

    共 n 行,第 i 行输出一个正整数 titi 表示第 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 。

    备注:

    1n105,1ai,bi1091≤n≤105,1≤ai,bi≤109


    解题思路:像那二维偏序问题,先对a,b数组进行离散化处理一下,然后再按b值从大到小排一下序,然后从前往后对于第i个妹子的等级为比她的a值大的妹子中等级最大值加1,然后再将这个妹子的等级更新到线段树中。
    代码:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+7;
    int n;
    struct node{
        int a,b;
        int id,rk;
    }p[maxn];
    int Max[maxn*4];
    bool cmp(node x,node y){
        return x.b>y.b;
    }
    bool cmp1(node x,node y){
        return x.a<y.a;
    }
    bool cmp2(node x,node y){
        return x.b<y.b;
    }
    bool cmp3(node x,node y){
        return x.id<y.id;
    }
    void pushup(int rt){
        Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
    }
    void update(int pos,int val,int l,int r,int rt){
        if(l==r){
            Max[rt]=val;
            return;
        }
        int mid=(l+r)/2;
        if(mid>=pos) update(pos,val,l,mid,rt<<1);
        if(mid<pos) update(pos,val,mid+1,r,rt<<1|1);
        pushup(rt);
    }
    int ask(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r)
            return Max[rt];
        int mid=(l+r)/2;
        int ans=0;
        if(L<=mid) ans=max(ans,ask(L,R,l,mid,rt<<1));
        if(R>mid) ans=max(ans,ask(L,R,mid+1,r,rt<<1|1));
        return ans;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%d%d",&p[i].a,&p[i].b);
            p[i].id=i;
        }
        sort(p+1,p+1+n,cmp1);
        for(int i=1;i<=n;i++) p[i].a=i;
        sort(p+1,p+1+n,cmp2);
        for(int i=1;i<=n;i++) p[i].b=i;
        sort(p+1,p+1+n,cmp); //按b值从大到小排
        for(int i=1;i<=n;i++){
            p[i].rk=ask(p[i].a,n,1,n,1)+1;//查找大于当前妹子a值的等级最大值再加1
            update(p[i].a,p[i].rk,1,n,1); //将第i个妹子的等级更新到线段树中
        }
        sort(p+1,p+1+n,cmp3);
        for(int i=1;i<=n;i++) 
            printf("%d
    ",p[i].rk);
        return 0;
    }
  • 相关阅读:
    Vim作者创造新编程语言Zimbu
    Google Maps API编程资源大全
    好网收集的地址
    三种模拟自动登录和提交POST信息的实现方法
    解析VMware三种网络连接方式
    PostgreSQL 创建帐号,数据库,权限
    LINUX目录详解
    Linux流媒体服务器安装配置
    用RAMDISK来提高PostgreSQL访问速度
    PostgreSQL 集群复制方案之使用pgq和londiste工具包
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/11187425.html
Copyright © 2020-2023  润新知