继续线段树。
这个题的意思是,有很多人,然后后面往前面插队神马的。开始没看懂,没注意下面的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; }