poj2182 Lost Cows (线段树)
2015-08-16 14:03
357 查看
传送门
大意:有一个1-n的排列,数据给出从第二个到第n个数中的每一个数前面有几个数比这个数小,要求还原这个1-n的排列
思路:最近做这种题好像有点感觉了,很自然的想到,我们可以从最后一个数来倒推,一直推出第一个过后就可以完事了。这样的话,我们很容易写出一个N² 的算法。但作为一名OIer,我们要求上进,所以我们就会想,可不可以优化一下呢。其实我们发现,在找前面出现了几个比目标值小的操作很冗余,我们可以考虑用线段树来优化。那么我们就可以在O(NlogN) 的时间内求出来整个序列
代码:
大意:有一个1-n的排列,数据给出从第二个到第n个数中的每一个数前面有几个数比这个数小,要求还原这个1-n的排列
思路:最近做这种题好像有点感觉了,很自然的想到,我们可以从最后一个数来倒推,一直推出第一个过后就可以完事了。这样的话,我们很容易写出一个N² 的算法。但作为一名OIer,我们要求上进,所以我们就会想,可不可以优化一下呢。其实我们发现,在找前面出现了几个比目标值小的操作很冗余,我们可以考虑用线段树来优化。那么我们就可以在O(NlogN) 的时间内求出来整个序列
代码:
#include<cstdio> #define MAXN 8005 struct node { int l, r, len; }t[MAXN * 4]; void Build(int i, int l, int r) { t[i].l = l, t[i].r = r; t[i].len = r-l+1; if(l == r) return; int mid = (l + r) >> 1; Build(i<<1, l, mid); Build(i<<1|1, mid + 1, r); } int Q(int i, int num) { -- t[i].len; if(t[i].l == t[i].r) return t[i].l; if(num > t[i<<1].len) return Q(i<<1|1, num - t[i<<1].len); else return Q(i<<1, num); } int n, a[MAXN], ans[MAXN]; int main() { scanf("%d", &n); Build(1, 1, n); for(int i = 2; i <= n; i ++) scanf("%d", &a[i]); for(int i = n; i > 0; i --) ans[i] = Q(1, a[i] + 1); for(int i = 1; i <= n; i ++) printf("%d\n", ans[i]); }
相关文章推荐
- HDU 5047 Sawtooth (JAVA大数类)
- [python leetcode] Word Ladder II (very hard)[非常难,放弃]
- poj2182 Lost Cows (线段树)
- PAT 01-2. Maximum Subsequence Sum (25) - Python
- ROADS
- 布局动画 属性初始 android:animateLayoutChanges
- HDU1542线段树面积并
- ROADS
- 石头剪子布游戏
- java函数
- python选择排序实现法
- 46 个非常有用的 PHP 代码片段
- 回文树【处理一类回文串问题的强力工具】
- xcode的主函数界面详解
- Spring事务的传播行为和隔离级别
- Socket编程
- 一个java定时器功能
- 高德地图之地图篇----->定位的蓝点、添加Marker
- LightOJ 1275 - Internet Service Providers
- 责任链模式