31492 20523 3890 19243
采用倒序插入,pos的意义就是找到一个位置,它的前面刚好有pos个空位,用一个empty数组记录区间[l,r]之间有多少个空位,然后进来一个p,比较左右子树的空位数,如果坐标的空位数 >= p,那么说明p应该放在左子树,否则,p应该放右子树,并且p还要减去左子树的空位数,因为右子树的空位数也是从0开始的。
推荐一个博客网站http://www.cnblogs.com/wally/p/3614721.html
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<stack> using namespace std; #define ll long long #define MAX 1<<<30 #define lson rt<<1 #define rson rt<<1|1 #define getMin(a,b) a<b?a:b #define getMax(a,b) a>b?a:b const int N=200005; int epy[N<<2]; int n,index,pos[N],id[N],ans[N]; void init(int l,int r,int rt) { epy[rt]=r-l+1; // printf("rt:%d epy:%d r:%d l:%d\n",rt,epy[rt],r,l); if (l==r) return; int mid=(l+r)>>1; init(l,mid,lson); init(mid+1,r,rson); } void update(int l,int r,int rt,int p) { epy[rt]--; if (l==r) { index=l; // printf("index:%d\n",index); return; } int mid=(l+r)>>1; if (epy[lson]>=p) update(l,mid,lson,p); else { p-=epy[lson]; update(mid+1,r,rson,p); } } int main() { int i; while (~scanf("%d",&n)) { for (i=1;i<=n;i++) scanf("%d%d",&pos[i],&id[i]); init(1,n,1); for (i=n;i>=1;i--) { update(1,n,1,pos[i]+1); ans[index]=id[i]; } for (i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; } 这里面有输出语句便于理解线段树的分级走向,对于这个题为什么要采取倒序,因为发生更改的条件是该位置已被前面的人占了,只能往后去找空位,所以要用倒序,至于为什么如果p大于empty[lson],还要减去empty[lson],因为它发生了状态转移,转移到了它的子树上,又相当于从头开始 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson rt << 1 #define rson rt << 1 | 1 const int MAXN = (200000 + 20); int empty[MAXN << 2]; int n, index, pos[MAXN], id[MAXN], ans[MAXN]; void Build(int L, int R, int rt) { empty[rt] = R - L + 1; printf("rt:%d empty:%d\n",rt,empty[rt]); if (L == R) return; int M = (L + R) >> 1; Build(L, M, lson); Build(M + 1, R, rson); } void Update(int L, int R, int rt, int p) { empty[rt]--; printf("//**============**//\n"); printf("rt:%d empty:%d\n",rt,empty[rt]+1); if (L == R) { index = L; printf("index:%d\n",index); return; } int M = (L + R) >> 1; if (empty[lson] >= p) printf("Left\n"),Update(L, M, lson, p); else p -= empty[lson], printf("p:%d lson:%d\nRight\n",p+empty[lson],lson),Update(M + 1, R, rson, p); } int main() { while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) { scanf("%d %d", &pos[i], &id[i]); } Build(1, n, 1); for (int i = n; i >= 1; i--) { Update(1, n, 1, pos[i] + 1); ans[index] = id[i]; } for (int i = 1; i <= n; i++) { printf(i == n ? "%d\n" : "%d ", ans[i]); } } return 0; }