题目传送:Lost Cows
思路:线段树,从后往前扫描,如果当前数字为n,则表示它是剩余的序列中(包括他自己)顺序后的第n+1个数。找到后删除,借助线段树可以达到快速删除的效果
AC代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <deque> #include <cctype> #define LL long long #define INF 0x7fffffff using namespace std; int n; int a[10005], ans[10005]; struct node { int l, r; int v; }; node s[30005]; void build(int l, int r, int rt) { //建树 s[rt].l = l; s[rt].r = r; s[rt].v = r - l + 1; if(l == r) return; int mid = (l + r) >> 1; build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1); } int query(int rt, int k) { //查询并且删除 s[rt].v --; if(s[rt].l == s[rt].r) return s[rt].l; else if(k <= s[rt << 1].v) { query(rt << 1, k); } else { query(rt << 1 | 1, k - s[rt << 1].v); } } int main() { scanf("%d", &n); for(int i = 2; i <= n; i ++) { scanf("%d", &a[i]); } a[1] = 0; build(1, n, 1); for(int i = n; i >= 1; i --) { //从后往前扫描,找到一个删除一个 ans[i] = query(1, a[i] + 1); } for(int i = 1; i <= n; i ++) { printf("%d\n", ans[i]); } return 0; }
原文地址:http://blog.csdn.net/u014355480/article/details/45678601