题意:
插队,从第一个人开始,选择自己站到第几个位置,之后再选,后面选的可以把前面选的挤到后面
思路:
线段树,从后到前,存空位。
PS: 自己写G++说什么都TLE,去看了看讨论区,C++才能够。
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
const int maxn=200010;
#define inf 0x3f3f3f3f
#define lson id<<1,left,mid
#define rson id<<1|1,mid+1,right
int a[maxn];
int pos[maxn];
int ans[maxn];
int res=0;
using namespace std;
struct node
{
int left,right,sum,num;
int mid;
}Tree[maxn*4];
int cnt=0,n;
void Build(int id,int left,int right)
{
Tree[id].left=left;
Tree[id].right=right;
if(left==right)
{
Tree[id].num=cnt++;
Tree[id].sum=1;
return ;
}
int mid=(left+right)>>1;
Build(lson);
Build(rson);
Tree[id].sum=Tree[id<<1].sum+Tree[id<<1|1].sum;
}
void add(int id,int aim)
{
if(Tree[id].left==Tree[id].right)
{
res=Tree[id].num;
Tree[id].sum=0;
return ;
}
if(aim<=Tree[id<<1].sum)
add(id<<1,aim);
else
add(id<<1|1,aim-Tree[id<<1].sum);
Tree[id].sum=Tree[id<<1].sum+Tree[id<<1|1].sum;
}
int main()
{
while(~scanf("%d",&n))
{
cnt=0;
Build(1,1,n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&pos[i],&a[i]);
}
for(int i=n-1;i>-1;i--)
{
res=0;
add(1,pos[i]+1);
ans[res]=a[i];
}
for(int i=0;i<n;i++)
{
if(i)
printf(" ");
printf("%d",ans[i]);
}
printf("\n");
}
return 0;
}