题目链接:https://i-beta.cnblogs.com/posts/edit
思路:对输入数据反向思考,那么输入的位置x代表他之前已经有x个人存在,
但是后面的人会插队,那么已经有x个人存在可以表示为,前面应该还有几个空位。
因为我们是反向遍历位置关系,那么我们只需要维护数组前面有x个空位就可。
1 #include <iostream> 2 #include <algorithm> 3 #include <map> 4 #include <queue> 5 #include <string> 6 #include <stack> 7 #include <vector> 8 #include <list> 9 #include <cstdio> 10 #include <cstring> 11 #include <cmath> 12 using namespace std; 13 #define ll long long 14 #define pb push_back 15 #define fi first 16 #define se second 17 #define lson(x) x<<1 18 #define rson(x) x<<1|1 19 20 21 const int N = 2e5+10; 22 struct node{ 23 int l,r,blank; 24 int mid(){ return (l+r)>>1; } 25 }tree[N<<2]; 26 int inx[N],v[N],que[N]; 27 int n,tim; 28 29 void build_tree(int rt, int l_b, int r_b){ 30 tree[rt].l = l_b; tree[rt].r = r_b; 31 if(l_b == r_b){ 32 tree[rt].blank = 1;//1代表有一个位置 33 return; 34 } 35 int mid = tree[rt].mid(); 36 build_tree(lson(rt), l_b, mid); 37 build_tree(rson(rt), mid + 1, r_b); 38 tree[rt].blank = tree[lson(rt)].blank + tree[rson(rt)].blank; 39 } 40 41 //减去这个位置 42 void update(int x){ 43 while(x != 1){ 44 tree[x].blank -= 1; 45 x >>= 1; 46 } 47 } 48 49 //找到这个位置 50 void search(int rt, int tot, int v){ 51 if(tree[rt].l == tree[rt].r){ 52 que[tree[rt].l] = v; 53 update(rt); 54 return; 55 } 56 //这个位置在左边 57 if(tree[lson(rt)].blank >= tot) search(lson(rt), tot, v); 58 //这个位置在右边 59 else search(rson(rt), tot - tree[lson(rt)].blank, v); 60 61 } 62 63 void solve(){ 64 while(~scanf("%d", &n)){ 65 tim = 0; 66 build_tree(1,1,n); 67 for(int i = 1; i <= n; ++i) scanf("%d%d", inx+i, v+i); 68 for(int i = n; i >= 1; --i){ 69 search(1, inx[i]+1, v[i]); 70 } 71 printf("%d", que[1]); 72 for(int i = 2; i <= n; ++i){ 73 printf(" %d", que[i]); 74 } 75 printf(" "); 76 } 77 } 78 79 int main(){ 80 81 // ios::sync_with_stdio(false); 82 // cin.tie(0); cout.tie(0); 83 solve(); 84 85 return 0; 86 }