刷题记录:牛客NC51101Lost Cows

news/2024/11/23 2:19:22/

传送门:牛客

题目描述:

(2≤N≤8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, 
they visited the neighborhood 'watering hole' and drank a few too many beers before dinner. When it 
was time to line up for their evening meal, they did not line up in the required ascending numerical 
order of their brands.
Regrettably, FJ does not have a way to sort them. Furthermore, he's not very good at observing 
problems. Instead of writing down each cow's brand, he determined a rather silly statistic: For each 
cow in line, he knows the number of cows that precede that cow in line that do, in fact, have smaller 
brands than that cow.
Given this data, tell FJ the exact ordering of the cows.
输入
5
1
2
1
0
输出:
2
4
5
3
1

方法一

首先本题有一个比较显然的解决方法,我们可以从最后一个人开始为他定编号,因为对于最后一个人来说,如果他选了aaa编号,那么对于它的前面的人来说,此时除了aaa,所有剩下的编号肯定都是有的,那么就说明我们现在的aaa编号在我们剩下的所有的编号的位置(从小到大)就是当前这个人前面比他小的个数+1.

那么此时我们的问题就变成了如何找出一段序列中排名为kkk的数字,并且支持单点删除操作.对于这个问题,我在这道题中有详细的解释,所以此处就不在赘述了.具体可参考代码

下面是具体的代码部分:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {ll x=0,w=1;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*w;
}
#define maxn 1000000
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3fc
struct Segment_tree{int l,r,sum;
}tree[maxn];
int n;
void pushup(int rt) {tree[rt].sum=tree[ls].sum+tree[rs].sum;
}
void build(int l,int r,int rt) {tree[rt].l=l;tree[rt].r=r;if(l==r) {tree[rt].sum=1;return ;}int mid=(tree[rt].l+tree[rt].r)>>1;build(lson);build(rson);pushup(rt);
}
void update(int pos,int rt) {if(tree[rt].l==pos&&tree[rt].r==pos) {tree[rt].sum=0;return ;}int mid=(tree[rt].l+tree[rt].r)>>1;if(pos<=mid) update(pos,ls);else update(pos,rs);pushup(rt);
}
int query(int l,int r,int rt,int k) {if(tree[rt].l==tree[rt].r) return tree[rt].l;int mid=(tree[rt].l+tree[rt].r)>>1;if(tree[ls].sum>=k) return query(l,mid,ls,k);else return query(mid+1,r,rs,k-tree[ls].sum);
}
int ans[maxn];int a[maxn];
int main() {n=read();build(root);for(int i=2;i<=n;i++) a[i]=read();for(int i=n;i>=2;i--) {ans[i]=query(1,n,1,a[i]+1);update(ans[i],1);}ans[1]=query(1,n,1,1);for(int i=1;i<=n;i++) {printf("%d\n",ans[i]);}return 0;
}

方法二

我们可以反向的去思考这道题.我们此时考虑对排在前iii位的人分配我们的相对编号大小.那么对于第iii个人来说,我们之前的所有i−1i-1i1位人显然都是排在这个人前面的,所以我们要将第iii个人插在i−1i-1i1排好的编号之中,并且满足当前的需求即可.因为对于插入操作来说,我们并不影响之前的i−1i-1i1的相对编号大小.

以样例为例(下标为编号):
对于第一只奶牛,在它之前没有奶牛,所以编号为1:1
对于第二只奶牛,在它之前有1只奶牛编号比它小,所以编号为2:1 2
对于第三只奶牛,在它之前有2只奶牛编号比它小,在它之前实际也只有两只奶牛,所以编号为3:1 2 3
对于第四只奶牛,由样例,在它之前有1只奶牛编号比它小,而在他前面有三个奶牛,所以此时它的编号应该大于三个奶牛中的两个,所以此时将他的编号赋为4,其他奶牛编号顺延:1 4 2 3
对于第五只奶牛,解决方法同第四只,编号赋值为1:5 1 4 2 3

对于插入操作,最优的写法显然是链表,但是由于此题的数据不多,才800080008000,所以此时我们直接使用vectorvectorvector来进行维护依旧是可以接受的,复杂度为n∗(n+1)/2n*(n+1)/2n(n+1)/2,差不多为3e73e73e7左右

下面是具体的代码部分:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {ll x=0,w=1;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*w;
}
#define maxn 1000000
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3f
vector<int>v;
int a;int ans[maxn];
int main() {int n=read();v.insert(v.begin(),1);for(int i=2;i<=n;i++) {a=read();v.insert(v.begin()+a,i);}for(int i=0;i<v.size();i++) {ans[v[i]]=i+1;}for(int i=1;i<=n;i++) {cout<<ans[i]<<endl;}return 0;
}

http://www.ppmy.cn/news/25916.html

相关文章

Win10搭建Pyspark2.4.4+Pycharm开发环境(亲测可用)

下载资源hadoop3.0.0spark-2.4.4-bin-without-hadoopwinutils下载(对应hadoop3.0.1的bin目录覆盖本地hadoop的bin目录)jdk1.8(默认已按照配置)conda/anaconda(默认已安装)注意:cdh6.3.2的spark为2.4.0但是使用2.4.0本地pyspark有bug,下载的文件可能在第一次解压缩后,如未出现目…

LeetCode-1237. 找出给定方程的正整数解【双指针,二分查找】

LeetCode-1237. 找出给定方程的正整数解【双指针&#xff0c;二分查找】题目描述&#xff1a;解题思路一&#xff1a;双指针。首先我们不管f是什么&#xff0c;即function_id等于什么不管。但是我们可以调用customfunction中的f函数&#xff0c;然后我们遍历x,y(1 < x, y &l…

C++模板(一)

文章目录C模板&#xff08;一&#xff09;1. 泛型编程2. 函数模板2.1 函数模板格式2.2 模板原理2.3 模板实例化2.4 模板参数匹配原则3. 类模板3.1 类模板格式3.2 背景3.3 类模板的实例化C模板&#xff08;一&#xff09; 1. 泛型编程 前面我们学到了函数重载这个特性&#xf…

基础篇—CSS padding(填充\内边距)解析

CSS padding(填充) CSS padding(填充)是一个简写属性,定义元素边框与元素内容之间的空间,即上下左右的内边距。 属性说明padding使用简写属性设置在一个声明中的所有填充属性padding-bottom设置元素的底部填充padding-left设置元素的左部填充padding-right设置元素的右部…

白话C#之委托

一、什么是委托&#xff1f; 书本上是这样来定义委托的&#xff1a; 委托是一种动态调用方法的类型&#xff0c;属于引用型。委托是对方法的抽象和封装。委托对象实质上代表了方法的引用&#xff08;即内存地址&#xff09;。委托通常是委托某个方法来实现具体的功能。当我们调…

SpringBoot社区版专业版带你配置热部署

&#x1f49f;&#x1f49f;前言 ​ 友友们大家好&#xff0c;我是你们的小王同学&#x1f617;&#x1f617; 今天给大家打来的是 SpringBoot社区版专业版带你配置热部署 希望能给大家带来有用的知识 觉得小王写的不错的话麻烦动动小手 点赞&#x1f44d; 收藏⭐ 评论&#x1…

【JavaGuide面试总结】Redis篇·中

【JavaGuide面试总结】Redis篇中1.Redis 单线程模型了解吗&#xff1f;2.Redis6.0 之后为何引入了多线程&#xff1f;3.Redis 是如何判断数据是否过期的呢&#xff1f;4.过期的数据的删除策略了解么&#xff1f;5.Redis 内存淘汰机制了解么&#xff1f;6.什么是 RDB 持久化&…

Python 之 Matplotlib 柱状图(竖直柱状图和水平柱状图)、直方图和饼状图

文章目录一、柱状图二、竖直柱状图1. 基本的柱状图2. 同位置多柱状图3. 堆叠柱状图三、水平柱状图1. 基本的柱状图2. 同位置多柱状图3. 堆叠柱状图四、直方图 plt.hist()1. 返回值2. 添加折线直方图3. 不等距分组4. 多类型直方图5. 堆叠直方图五、饼状图 pie()1. 百分比显示 pe…