POJ 2182 Lost Cows 线段树
2015-04-09 20:54
387 查看
这题的意思是给你N头牛,N-1个数据,每个数据代表当前编号前面比他小的牛,如样例5,1,2,1,0;2,4,5,3,1。意思就是有5头牛,第二头牛的前面有1头牛编号比他小,第三头牛前面有2头牛比他小,第四头牛前面有1头牛比他小,第五头牛前面没有牛比他小。 所以答案就是2,4,5,3,1。那么思想是什么呢?我们逆序去看,最后一头牛的编号一定是输入数字加一,这题看最后一个0,意思就是前面没有牛比他小,那么他的编号势必是1,去掉1,前面有1头牛比他小,剩下还有2,3,4,5。那么这答案便是3了。后面以此类推。
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stack> #define mem(a) memset(a, 0, sizeof(a)) #define maxn 8000 using namespace std; int ans[maxn + 5], w = 0; struct tree { int sum; int suml; }tr[maxn * 4 + 5]; void build(int l, int r, int n) { tr .sum = (r - l + 1); if(l == r) return; int mid = (l + r) / 2; build(l, mid, n * 2); build(mid + 1, r, n * 2 + 1); tr .suml = tr[n * 2].sum; } void res(int l, int r, int n, int num) { if(l == r&&tr .sum == num) { ans[w] = l; w++; tr .sum--; return; } int mid = (l + r) / 2; if(num <= tr .suml) res(l, mid, n * 2, num); else res(mid + 1, r, n * 2 + 1, num - tr .suml); tr .sum = tr[n * 2].sum + tr[n * 2 + 1].sum; tr .suml = tr[n * 2].sum; } int main() { int n, i, a; stack<int> st; while(scanf("%d", &n) != EOF) { mem(tr); mem(ans); w = 0; build(1, n, 1); for(i = 0;i < (n - 1);i++) { scanf("%d", &a); st.push(a); } while(!st.empty()) { a = st.top(); st.pop(); res(1, n, 1, a + 1); } res(1, n, 1, 1); for(i = (w - 1);i >= 0;i--) printf("%d\n", ans[i]); } return 0; }
相关文章推荐
- POJ 2182 Lost Cows (树状数组 or 线段树)
- poj-2182-Lost Cows (树状数组,线段树)
- poj 2182 Lost Cows 暴力或者用线段树 + poj2828Buy Tickets
- POJ 2182 Lost Cows(牛排序,线段树)
- 【POJ】 2182 - Lost Cows 【线段树入门】
- POJ 2182 Lost Cows 线段树
- POJ 2182 Lost Cows (树状数组+二分 / 线段树 / 枚举)
- Poj 2182 Lost Cows 线段树
- POJ 题目2182 Lost Cows(线段树)
- POJ - 2182 - Lost Cows (线段树)
- POJ 2182 Lost Cows 线段树
- POJ 2182 Lost Cows(牛排序,线段树)
- poj 2182 Lost Cows (单点线段树)
- 【POJ 2182 Lost Cows】+ 线段树
- poj 2182 Lost Cows 线段树
- Lost Cows POJ - 2182 线段树||树状数组+二分
- poj 2182 Lost Cows (线段树)
- Poj(2182)——Lost Cows(线段树)
- poj 2182 -Lost Cows -线段树-还原逆序数组
- poj 2182 Lost Cows(线段树经典题)