题目大意:火车站正在排队,有人插队(竟插队成功?),给出插入的位置,和那个人权值,求最后形成的队列。
分析:一直没想出来怎么做,只知道肯定要用树来做,不然绝对超时。然后,搜到一份蛮容易看懂的题解
http://www.cnblogs.com/CheeseZH/archive/2012/04/29/2476134.html
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 200010; struct Tree { int a, w; }; struct Node { int p, w; }; int n; Tree t[3*maxn]; Node q[maxn]; void Build(int root, int l, int r) { t[root].a = r-l+1; t[root].w = -1; if(l != r) { Build(2*root+1, l, (l+r)/2); Build(2*root+2, (l+r)/2+1, r); } } void Insert(int root, int l, int r, int p, int w) { t[root].a--; if(l == r) { t[root].w = w; } else if(t[2*root+1].a < p) { Insert(2*root+2, (l+r)/2+1, r, p-t[2*root+1].a, w); } else { Insert(2*root+1, l, (l+r)/2, p, w); } return; } void Print(int root, int l, int r) { if(l == r) { printf("%d ", t[root].w); return; } Print(2*root+1, l, (l+r)/2); Print(2*root+2, (l+r)/2+1, r); return; } int main() { while(~scanf("%d", &n)) { Build(0, 1, n); for(int i = 0; i < n; i++) { int p, w; scanf("%d%d", &p, &w); q[i].p = p+1, q[i].w = w; } for(int i = n-1; i >= 0; i--) Insert(0, 1, n, q[i].p, q[i].w); Print(0, 1, n); printf("\n"); } return 0; }