大意:有一个1-n的排列,数据给出从第二个到第n个数中的每一个数前面有几个数比这个数小,要求还原这个1-n的排列 思路:最近做这种题好像有点感觉了,很自然的想到,我们可以从最后一个数来倒推,一直推出第一个过后就可以完事了。这样的话,我们很容易写出一个N² 的算法。但作为一名OIer,我们要求上进,所以我们就会想,可不可以优化一下呢。其实我们发现,在找前面出现了几个比目标值小的操作很冗余,我们可以考虑用线段树来优化。那么我们就可以在O(NlogN) 的时间内求出来整个序列
代码:
#include#define MAXN 8005struct 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]);}