题意:有n头牛,标号从1到n,现在牛排成一个队列,知道每个牛的前面比自己标号小的牛的数量,输出每个牛的标号。
题解:给出的序列的最后一个数字是可以推出的,然后把这个数字拿走,又能知道前面有几个数字,和之前做过的有几个空位一个道理,维护线段树区间解决。
#include
#include
#include
using namespace std; const int N = 8005; int n, a[N], sum[N << 2], res[N]; void pushup(int k) { sum[k] = sum[k * 2] + sum[k * 2 + 1]; } void build(int k, int left, int right) { if (left == right) { sum[k] = 1; return; } int mid = (left + right) / 2; build(k * 2, left, mid); build(k * 2 + 1, mid + 1, right); pushup(k); } int modify(int k, int left, int right, int x) { sum[k]--; if (left == right) return left; int mid = (left + right) / 2; if (x <= sum[k * 2]) return modify(k * 2, left, mid, x); else return modify(k * 2 + 1, mid + 1, right, x - sum[k * 2]); } int main() { while (scanf(%d, &n) == 1) { build(1, 1, n); for (int i = 1; i < n; i++) scanf(%d, &a[i]); for (int i = n - 1; i >= 0; i--) res[i] = modify(1, 1, n, a[i] + 1); for (int i = 0; i < n; i++) printf(%d , res[i]); } return 0; }
?