今天做了两道线段树,还有 昨天的 Bestcoder ,发现线段树真是博大精深,题目的变形也是非常有意思,不想不知道,一想真奇妙。
思路 倒着插,为什么呢?首先最后一个的位置是确定的,倒着放的时候 n-1个是不会对第 n 个产生影响 ,所以放哪就放那了,不会发生变动,那么复杂度就是 O(n)的,怎么用线段树呢?我们思考这样一个问题,对于 i,如果我放第i个,
那么我一定要腾出 i-1个空位 来放 前面的数,所以 线段树的结构 就很明显了 ,用一个变量 记录 这段区间的空余位置
如果剩余的位置 >= i ,也就是放在lson我们 就直接放进去好了,但是如果不够呢,那么我们只能放在rson 的 i-lson的空位出。。。
#include<iostream>
#include<cstdio>
#define lson id << 1
#define rson id << 1|1
using namespace std;
struct line{
int l,r,len;
int mid(){
return (l + r) / 2;
}
}node[1000008];
int a[200002],b[200002],tmp[200002];
void _Tree(int id ,int l,int r)
{
node[id].l = l;node[id].r = r,node[id].len = r - l + 1;
if(l == r) return;
int mid = node[id].mid();
_Tree(lson,l,mid);
_Tree(rson,mid+1,r);
}
void _insert(int id,int k,int n)
{
node[id].len --;
if(node[id].l == node[id].r )
{
tmp[node[id].l] = b[n];return;
}
if(node[lson].len >=k)_insert(lson,k,n);
else if(node[rson].len >= k-node[lson].len)_insert(rson,k-node[lson].len,n);
}
int main()
{
int n,m;
while(~scanf("%d",&n))
{
_Tree(1,1,n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);a[i]++;
}
for(int i=n;i>=1;i--)
_insert(1,a[i],i);
for(int i=1;i<n;i++)
printf("%d ",tmp[i]);
printf("%d\n",tmp[n]);
}
}