继续线段树。
这个题的意思是,有很多人,然后后面往前面插队神马的。开始没看懂,没注意下面的HINT = =。。
看discuss说的从后往前建神马的,每次找第pos个空位。可是,肿么转换成线段树呢。
如果线段是空位的话是不行的啊,空位毕竟还是会更新的,但是线段长度是不变的啊。
想了一种方法,很麻烦啊。就是每个节点中存两个值,一个是左子树的空位的个数,一个是右子树空位的个数,然后就相当于类似二分查找了。
如果比左子树的空位的值大那么就去右子树中找,注意,这时候查找的值要变了,变成需要的空位N - 左子树空位的个数。(因为右子树的空位也是从0,1,2。。。开始的)。
交了,G++ TLE,C++2000+MS T T .。。
后搜题解,人家的貌似和我的差不多,但是我的却是看着繁。一个节点存了5个值 = =。。人家的三个就够了。后改了改,只要一个sum,完全可以满足原来的想法。
1700+MS,G++ 3700+MS。。。好弱。。
I 时间少的。。
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
using namespace std;
const int MAX = 200010;
struct Tnode{int l,r,sum;};
struct NODE{int pos,val;};
NODE a[MAX];
Tnode node[MAX<<2];
int ind[MAX];
int K;
void init()
{
memset(node,0,sizeof(node));
}
void Updata_sum(int t)
{
node[t].sum = node[R(t)].sum + node[L(t)].sum;
}
void Build(int t,int l,int r)
{
node[t].l = l; node[t].r = r;
node[t].sum = 0;
if( l == r - 1 )
{
node[t].sum = 1;
return ;
}
int mid = MID(l,r);
Build(L(t),l,mid);
Build(R(t),mid,r);
Updata_sum(t);
}
void Updata(int t,int l)
{
if( node[t].l == node[t].r - 1 )
{
node[t].sum = 0;
K = node[t].l;
return ;
}
if( l < node[L(t)].sum )
Updata(L(t),l);
else
Updata(R(t),l-node[L(t)].sum);
Updata_sum(t);
}
int main()
{
int n;
int pos,val;
while( ~scanf("%d",&n) )
{
init();
Build(1,0,n+1);
for(int i=0; i<n; i++)
scanf("%d %d",&a[i].pos,&a[i].val);
for(int i=n-1; i>=0; i--)
{
Updata(1,a[i].pos);
ind[K] = a[i].val;
}
for(int i=0; i<n-1; i++)
printf("%d ",ind[i]);
printf("%d\n",ind[n-1]);
}
return 0;
}
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
using namespace std;
const int MAX = 200010;
struct Tnode{int l,r,ls,rs;};
struct NODE{int pos,val;};
NODE a[MAX];
Tnode node[MAX<<2];
int ind[MAX];
int K;
void init()
{
memset(node,0,sizeof(node));
}
void Updata_sum(int t)
{
node[t].ls = node[L(t)].ls + node[L(t)].rs;
node[t].rs = node[R(t)].ls + node[R(t)].rs;
}
void Build(int t,int l,int r)
{
node[t].l = l; node[t].r = r;
node[t].ls = node[t].rs = 0;
if( l == r - 1 )
{
node[t].ls = 0;
node[t].rs = 1;
return ;
}
int mid = MID(l,r);
Build(L(t),l,mid);
Build(R(t),mid,r);
Updata_sum(t);
}
void Updata(int t,int l,int r)
{
if( node[t].l == node[t].r - 1 )
{
node[t].rs = 0;
K = node[t].l;
return ;
}
int mid = MID(node[t].l,node[t].r);
if( l < node[t].ls )
Updata(L(t),l,r);
else
Updata(R(t),l-node[t].ls,r-node[t].ls);
Updata_sum(t);
}
int main()
{
int n;
int pos,val;
while( ~scanf("%d",&n) )
{
init();
Build(1,0,n+1);
for(int i=0; i<n; i++)
scanf("%d %d",&a[i].pos,&a[i].val);
for(int i=n-1; i>=0; i--)
{
Updata(1,a[i].pos,a[i].pos+1);
ind[K] = a[i].val;
}
for(int i=0; i<n-1; i++)
printf("%d ",ind[i]);
printf("%d\n",ind[n-1]);
}
return 0;
}