zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    UVA756
    SP30906
    SP32900
    CF940F
    洛谷P5030
    洛谷P5142
    洛谷P2569
    网络流 24 题做题记录
    矩阵
    二分图
  • 原文地址:https://www.cnblogs.com/ZegWe/p/6139207.html
Copyright © 2011-2022 走看看