• [poj2182] Lost Cows (线段树)


    线段树


    Description

    N (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.

    Input

    • Line 1: A single integer, N

    • Lines 2..N: These N-1 lines describe the number of cows that precede a given cow in line and have brands smaller than that cow. Of course, no cows precede the first cow in line, so she is not listed. Line 2 of the input describes the number of preceding cows whose brands are smaller than the cow in slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in slot #3; and so on.

    Output

    • Lines 1..N: Each of the N lines of output tells the brand of a cow in line. Line #1 of the output tells the brand of the first cow in line; line 2 tells the brand of the second cow; and so on.

    Sample Input

    5
    1
    2
    1
    0

    Sample Output

    2
    4
    5
    3
    1


    题目大意

    1 ~ n 中的 n 个数以某一个顺序排列,给出这个排列中对于于第 2 到第 n 个数,在它前面并且比它小的数字个数。让你输出这个排列。

    题解

    这道题比较基本,和poj2828很相似,我就直接用那道题的代码改了。用线段树来维护每个数是否出现过。
    从后往前更新。
    例如样例 (0), 1, 2, 1, 0;
    先更新第 5 个位置,查询第 1 个还没出现过的数字,得到 1,将其赋值为 0 (已出现过),更新ans[5] = 1;
    然后更新第 4 个位置,查询第 2 个没出现过的数字,得到 3 ,更新ans[4] = 3;
    ......剩下的应该知道怎么做了吧,线段树中的值表示该区间中没有出现过的数的个数。

    代码

    #include <iostream>
    using namespace std;
    #define pushup(u) {sum[u] = sum[u<<1] + sum[u<<1|1];}
    #define ls u<<1,l,mid
    #define rs u<<1|1,mid+1,r
    
    const int maxn = 2e5 + 5;
    int sum[maxn << 2];
    int ans[maxn];
    int pos[maxn];
    
    void build(int u,int l,int r) {
    	sum[u] = r - l + 1;
    	if(l == r)return;
    	int mid = (l + r) >> 1;
    	build(ls);
    	build(rs);
    }
    
    int update(int u,int l,int r,int x,int a) {
    	if(l == r){
    		sum[u] = 0;
    		return l;
    	}
    	int res;
    	int mid = (l + r) >> 1;
    	if(sum[u << 1] >= x)res = update(ls,x,a);
    	else res = update(rs,x - sum[u<<1],a);
    	pushup(u);
    	return res;
    }
    
    int main() {
    	ios::sync_with_stdio(false); cin.tie(0);
    	int n;
    	while(cin >> n) {
    		build(1,1,n);
    		pos[1] = 0;
    		for(int i = 2;i <= n;i++) {
    			cin >> pos[i];
    		}
    		for(int i = n;i > 0;i--) {
    			ans[i] = update(1,1,n,pos[i] + 1,i);
    		}
    		for(int i = 1;i <= n;i++) {
    			cout << ans[i] << endl;
    		}
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    经常使用排序算法时间复杂度和空间复杂度简析
    Android触碰事件
    opencv矩阵运算(2)
    [ACM] HDU 1400 Mondriaan&#39;s Dream (状态压缩,长2宽1长方形铺满)
    指针知识梳理8- 指针的指针
    Git学习笔记(一)
    Object-c Associated Object
    YTUOJ-计算该日在本年中是第几天(用户自己定义类型)
    MYSQL源代码编译的变动
    手机端小问题整理
  • 原文地址:https://www.cnblogs.com/ZegWe/p/6139207.html
Copyright © 2020-2023  润新知