博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj2182(线段树求序列第k小)
阅读量:6897 次
发布时间:2019-06-27

本文共 1016 字,大约阅读时间需要 3 分钟。

题目链接:https://vjudge.net/problem/POJ-2182

题意:有n头牛,从1..n编号,乱序排成一列,给出第2..n个牛其前面有多少比它编号小的个数,记为a[i],求该序列的完整编号ans[i]。

思路:最近几天开始学线段树,加油!!我们从序列最后一个开始,则可以确定ans[n]=a[n]+1,然后把编号a[n]+1删除,继续判断倒数第二个...而这一求序列中第k小的数可通过线段树来完成。线段树结点包含l(区间左端点),r(区间右端点),len(区间剩余的编号个数)。每次查询时维护len属性,若k<=左子树的len,则遍历左子树,否则遍历右子树。

AC代码:

#include
using namespace std;const int maxn=8005;struct node{ int l,r,len;}tr[4*maxn];int n,a[maxn],ans[maxn];void build(int v,int l,int r){ tr[v].l=l,tr[v].r=r,tr[v].len=r-l+1; if(l==r) return; int mid=(l+r)>>1; build(2*v,l,mid); build(2*v+1,mid+1,r);}int query(int v,int k){ --tr[v].len; if(tr[v].l==tr[v].r) return tr[v].r; if(k<=tr[2*v].len) query(2*v,k); else query(2*v+1,k-tr[2*v].len);}int main(){ scanf("%d",&n); for(int i=2;i<=n;++i) scanf("%d",&a[i]); build(1,1,n); for(int i=n;i>=1;--i) ans[i]=query(1,a[i]+1); for(int i=1;i<=n;++i) printf("%d\n",ans[i]); return 0;}

 

转载于:https://www.cnblogs.com/FrankChen831X/p/10778829.html

你可能感兴趣的文章
7.3 进制转换
查看>>
初始Ajax
查看>>
[杂记]如何在ppt里插入高亮代码
查看>>
Android中高效的显示图片之二——在非UI线程中处理图片
查看>>
PV、UV、IP之间的区别与联系
查看>>
ssh 操作 esxi 基本命令
查看>>
调用HtmlTestRunner生成测试报告为空
查看>>
最优装载(贪心)
查看>>
DAY10-MYSQL数据类型
查看>>
【学时总结】◆学时·VII◆ 高维DP
查看>>
SQL Server进制
查看>>
简单的编辑器
查看>>
Android 数据库管理— — —更新数据
查看>>
cmd命令
查看>>
算法笔记 --- Counting Sort
查看>>
LeetCode 88 Merge Sorted Array
查看>>
HDU 3974 Assign the task
查看>>
Java并发之(3):锁
查看>>
11.2JS笔记
查看>>
oracle11G 命令【导库数量对比】
查看>>