当前位置: 首页 > news >正文

刷题记录:牛客NC51101Lost Cows

传送门:牛客

题目描述:

(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.lryc.cn/news/11065.html

相关文章:

  • 华为OD机试 - 不等式 | 备考思路,刷题要点,答疑 【新解法】
  • GuLi商城-SpringCloud-OpenFeign测试远程调用
  • 阿里云_山东鼎信短信的使用(云市场)
  • 基于虚拟机机的代码保护技术
  • Win10耳机有声音麦不能说话怎么办?麦克风说话别人听不到解决方法
  • The 22nd Japanese Olympiad in Informatics (JOI 2022/2023) Final Round 题解
  • openEuler RISC-V 成功适配 VisionFive 2 单板计算机
  • 2005-2022中国企业对外直接投资、OFDI海外投资明细、中国全球投资追踪数据CGIT(含非建筑施工类问题投资)
  • PCB学习笔记——使用嘉立创在线绘制原理图与PCB
  • 【C++】类型转化
  • Mybatis -- resultMap以及分页
  • Linux之进程
  • 结构体——“C”
  • CCNP350-401学习笔记(51-100题)
  • C语言学习_DAY_4_判断语句if_else和分支语句switch_case【C语言学习笔记】
  • 实验07 赫夫曼编码及综合2022(带程序填空)
  • 分布式 CAP BASE理论
  • 三调地类筛选器,Arcgis地类筛选
  • 华为OD机试 - 密室逃生游戏(Python)
  • 白话C#之委托
  • jsp高校教职工管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • 2023年数学建模美赛A题(A drought stricken plant communities)分析与编程
  • Delphi 中自定义鼠标指针图像
  • 【计算机网络】物理层
  • 华为OD机试 - 最少停车数(Python)
  • 面试题-前端开发JavaScript篇上(答案超详细)
  • 【计算机网络】运输层
  • 20222023华为OD机试 - 基站维修工程师(Python)
  • 21. 合并两个有序链表
  • 产品经理知识体系:5.如何做好产品数据分析?