后缀数组
poj 1743
poj 3415
poj 2758
线段树
poj 2828
每个人依次插队, pos表示这个人会差到第pos个人的右边, 树状数组维护,开始的时候全置1,表示每个位置都有一个人,就是最终的状态,然后按照时间顺序 倒序处理. 先处理最后一个人, 二分出前n项和等于其pos+1的位置, 那么这个人就会在这个位置, 对于最后一个人, 他恰好在 pos位置, 然后最后一个人的位置确定了, 树状数组改位置清零, 状态就是除去这个人的状态, 然后处理倒数第二个人, 以此类推. 线段树有个比较巧妙的写法,3年前的工作了, 也贴一下吧. 虽然测试没快多少, 但是树状数组n*logn*logn,因为有二分, 线段树只有nlogn. 线段树结点存区间的和, 查询一个值时, 左儿子和如果足够,就走左边, 否则减去左边的和,剩余部分走右边,返回走到叶子结点的id.
array
1 //#define txtout 2 //#define debug 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<stack> 13 #include<queue> 14 #include<set> 15 #include<map> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double pi=acos(-1.0); 20 const double eps=1e-8; 21 const int inf=0x3f3f3f3f; 22 const int M=2e5+10; 23 class One_Tree_Array { ///一维树状数组 24 static const int M=2e5+10; ///点的个数 25 typedef int typev; 26 typev a[M]; 27 int n; 28 public: 29 void init(int tn) { ///传入点数,点下标 1 开始 30 n=tn; 31 for(int i=0; i<=n; i++) a[i]=0; 32 } 33 int lowb(int t) { 34 return t&(-t); 35 } 36 void add(int i,typev v) { 37 for(; i<=n; a[i]+=v,i+=lowb(i)); 38 } 39 typev sum(int i) { 40 typev s=0; 41 for(; i>0; s+=a[i],i-=lowb(i)); 42 return s; 43 } 44 } tree; 45 int n; 46 struct Q { 47 int pos,val; 48 } p[M]; 49 int answer[M]; 50 int Binary(int x){ 51 int L=0,R=n-1,result=0; 52 while(L<=R){ 53 int mid=(L+R)>>1; 54 if(tree.sum(mid+1)>=x){ 55 result=mid; 56 R=mid-1; 57 } 58 else{ 59 L=mid+1; 60 } 61 } 62 return result; 63 } 64 void solve() { 65 tree.init(n); 66 for(int i=1;i<=n;i++){ 67 tree.add(i,1); 68 } 69 for(int i=n-1;i>=0;i--){ 70 int to=Binary(p[i].pos+1); 71 answer[to]=p[i].val; 72 tree.add(to+1,-1); 73 } 74 } 75 int main() { 76 #ifdef txtout 77 freopen("in.txt","r",stdin); 78 freopen("out.txt","w",stdout); 79 #endif // txtout 80 while(~scanf("%d",&n)) { 81 for(int i=0; i<n; i++) { 82 scanf("%d%d",&p[i].pos,&p[i].val); 83 } 84 solve(); 85 for(int i=0; i<n; i++) { 86 if(i) putchar(' '); 87 printf("%d",answer[i]); 88 } 89 puts(""); 90 } 91 return 0; 92 }