244. 谜一样的牛(树状数组、权值线段树)

简介: 笔记

题意


有 n头奶牛,已知它们的身高为 1 ~ n  且各不相同,但不知道每头奶牛的具体身高。


现在这 n  头奶牛站成一列,已知第 i 头牛前面有 A i头牛比它低,求每头奶牛的身高。


输入格式


第 1 行:输入整数 n 。


第 2  ~ n 行:每行输入一个整数 A i 第 i 行表示第 i 头牛前面有 A i

 头牛比它低。

(注意:因为第 1 头牛前面没有牛,所以并没有将它列出)


输出格式


输出包含 n 行,每行输出一个整数表示牛的身高。


第 i行输出第 i  头牛的身高。


数据范围


1<=n<=10^5

输入样例:


5

1

2

1

0


输出样例:


2

4

5

3

1


思路


从后向前遍历,能够确定当前牛的排名,a[i]+1。

由于我们已经确定了 [i+1,n] 头牛的位置。所以在确定第 i头牛的位置时,考虑的是区间[1,n] 中除去后面这些牛的第a[i]+1 小的位置。


代码


树状数组


二分确定位置

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int tr[N], a[N], b[N];
int n;
void add(int x, int c) {
    for (; x <= N; x += x & -x) tr[x] += c;
}
int sum(int x) {
    int res = 0;
    for (; x; x -= x & -x) res += tr[x];
    return res;
}
int main()
{
    cin >> n;
    add(1, 1);
    for (int i = 2; i <= n; i ++ ) cin >> a[i], add(i, 1);
    for (int i = n; i >= 1; i--) {
        int l = 1, r = n;
        while(l < r) {
            int mid = l + r >> 1;
            if(sum(mid) >= a[i] + 1) r = mid;
            else l = mid + 1;
        }
        b[i] = l;
        add(l, -1);
    }
    for (int i = 1; i <= n; i ++ ) cout << b[i] << endl;
    return 0;
}
  • 权值线段树
  • query:即等同于二分操作
#include <iostream>
#include <cstring>
#include <algorithm>
#define ls u<<1
#define rs u<<1|1
using namespace std;
const int N = 100010;
int n;
int a[N], b[N];
int tr[N << 2], L[N << 2], R[N << 2];
void pushup(int u) {
    tr[u] = tr[ls] + tr[rs];
}
void build(int u, int l, int r) {
    L[u] = l, R[u] = r;
    if(l == r) { tr[u] = 1; return ;}
    int mid = l + r >> 1;
    build(ls, l, mid), build(rs, mid + 1, r);
    pushup(u);
}
void query(int u, int k, int &res) {
    int ll = L[u], rr = R[u];
    if(ll == rr) {tr[u] = 0; res = /*n - ll + 1*/ ll; return ; }
    if(tr[ls] >= k) query(ls, k, res);
    else query(rs, k - tr[ls], res);
    pushup(u);
}
int main()
{
    cin >> n;
    for (int i = 2; i <= n; i++) cin >> a[i];
    build(1, 1, n);
    // int cnt = 0; // 当前选出了多少人
    for (int i = n; i >= 1; i--) {
        query(1, /*n - cnt -  a[i]*/ a[i] + 1, b[i]); 
        // cnt++;
    }
    for (int i = 1; i <= n; i++) cout << b[i] << endl;
    return 0;
}


相关文章
|
1月前
|
设计模式 安全 Java
Java设计模式(一):单例模式与工厂模式
本文详解单例模式与工厂模式的核心实现及应用,涵盖饿汉式、懒汉式、双重检查锁、工厂方法、抽象工厂等设计模式,并结合数据库连接池与支付系统实战案例,助你掌握设计模式精髓,提升代码专业性与可维护性。
|
1月前
|
数据采集 人工智能 数据可视化
GitHub 15.8k star 狂涨 DeerFlow,AI + 搜索 + 报告输出一次搞定!
DeerFlow 是字节跳动开源的深度研究框架,集成语言模型、搜索爬虫与代码执行工具,支持自动化完成复杂研究任务并生成多模态报告。具备多智能体协作、强搜索能力、Python 数据分析及可视化、报告自动生成等功能,适用于学术研究、内容创作与企业分析,部署灵活,社区活跃。
174 2
|
5月前
|
Java 数据库连接 应用服务中间件
JavaWeb CRUD 与分页系统架构学习教程
本教程详细讲解了如何使用 Java Web 技术构建一个带有 CRUD 和分页功能的应用程序。以产品信息管理为例,采用 MVC 架构设计,涵盖 Servlet、JSP、JDBC/MyBatis 等技术。内容包括基础知识介绍、项目结构划分、数据库连接配置、DAO 层实现、Service 层设计、Servlet 控制层编写、JSP 前端展示以及分页功能的实现。同时涉及日志配置和 Tomcat 部署运行。通过分层开发,确保代码清晰、职责分明,便于维护和扩展。适合初学者掌握 Java Web 开发全流程,并为学习更高级框架奠定基础。
130 0
|
开发框架 前端开发 Java
【前端学java】SpringBootWeb极速入门-实现一个简单的web页面01
【8月更文挑战第12天】SpringBootWeb极速入门-实现一个简单的web页面01
345 3
【前端学java】SpringBootWeb极速入门-实现一个简单的web页面01
|
JSON 前端开发 Java
web前-JAVA后端 数据API接口交互协议
目前热门的主流web前端和Java后端数据技术架构:设备端和后台服务端,两者之间主要有两类的数据流和一类的控制流进行数据的交互。
web前-JAVA后端 数据API接口交互协议
|
存储 SQL 算法
数据脱敏技术与应用
数据脱敏技术与应用
数据脱敏技术与应用
|
网络协议 安全
内网接入外网的几种方式
内网接入外网的几种方式
1110 0
|
运维
业务架构图规范
业务架构图规范
1712 0
业务架构图规范
|
监控 安全 项目管理
宜搭数字化ERP解决方案(二)|学习笔记
快速学习宜搭数字化ERP解决方案(二)
宜搭数字化ERP解决方案(二)|学习笔记
|
存储 安全 算法
Dataphin核心功能(四)安全:基于数据权限分类分级和敏感数据保护,保障企业数据安全
《数据安全法》的发布,对企业的数据安全使用和管理提出了更高的要求。Dataphin提供基于数据分级分类和数据脱敏的敏感数据识别和保护能力,助力企业建立合规的数据安全体系,保障企业数据安全。本篇,我们就来聊聊Dataphin的数据安全能力。

热门文章

最新文章