题目描述

解题思路
这个题目如果是从前往后找规律是很难找的,我们需要从最后一头牛看起,我们知道,最后一头牛只要知道了前面有多少比她小的,因为我们牛的编号只能是1-n,所以我们可以判断出最后一头牛的身高。判断了最后一头牛的身高之后,我们可以判断倒数第二头牛的身高。我们维护一个身高数组,从后往前枚举牛,只要确定了某头牛的身高,那么身高数组对应身高置0,否则是1。目前我们枚举到的牛前面有k个比她小,那么我们只需要找到身高数组1-m的前缀和为k就好,这头牛的身高就是m+1。查找可以二分优化。

代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import java.io.*; import java.util.*;
class Main{ public static int N = 100010,n; public static int[] cows = new int[N],lower = new int[N],c = new int[N],res = new int[N]; public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); public static int lowbit(int x){ return (-x) & x; } public static int get(int x){ int res = 0; for(int i = x;i > 0;i -= lowbit(i)) res += c[i]; return res; } public static void modify(int x,int k){ for(int i = x;i <= n;i += lowbit(i)) c[i] += k; } public static void main(String[] args)throws Exception{ n = Integer.parseInt(br.readLine()); modify(1,1); for(int i = 2;i <= n;i++) { lower[i] = Integer.parseInt(br.readLine()); modify(i,1); } for(int i = n;i >= 1;i--){ int l = 1,r = n; while(l < r){ int mid = (l + r + 1) >> 1; if(get(mid-1) > lower[i]) r = mid - 1; else l = mid; } modify(l,-1); res[i] = l; } for(int i = 1;i <= n;i++) bw.write(String.valueOf(res[i])+'\n'); bw.flush(); } }
|