Poj--2828(线段树,计数)

2014-10-01 20:44:42

思路:倒着考虑,比如现在考虑到了第 k 个,他要排到第 p 个位置,那么一定要让他前面有 p-1 个空位,用线段树维护即可,每个节点存这段区间内空位个数。、

 1 /*************************************************************************
 2     > File Name: 2828.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Wed 01 Oct 2014 05:50:31 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <queue>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 #define lpos (pos << 1)
18 #define rpos (pos << 1|1)
19 #define getmid(l,r) (l + (r - l) / 2)
20 typedef long long ll;
21 const int INF = 1 << 30;
22 const int maxn = 200010;
23 
24 int N;
25 int ans[maxn];
26 
27 struct node{
28     int val,num;
29 }t[maxn << 2];
30 
31 void Build_tree(int pos,int l,int r){
32     t[pos].num = r - l + 1;
33     if(l == r)
34         return;
35     int mid = getmid(l,r);
36     Build_tree(lpos,l,mid);
37     Build_tree(rpos,mid + 1,r);
38 }
39 
40 void Update(int p,int v,int pos,int l,int r){
41     if(l == r){
42         ans[l] = v;
43         t[pos].val = v;
44         t[pos].num = 0;
45         return;
46     }
47     int mid = getmid(l,r);
48     if(t[lpos].num >= p){
49         Update(p,v,lpos,l,mid);
50     }
51     else{
52         Update(p - t[lpos].num,v,rpos,mid + 1,r);
53     }
54     t[pos].num--;
55 }
56 
57 int main(){
58     int p[maxn],v[maxn];
59     while(~scanf("%d",&N)){
60         Build_tree(1,1,N);
61         for(int i = N; i >= 1; --i)
62             scanf("%d%d",&p[i],&v[i]);
63         for(int i = 1; i <= N; ++i)
64             Update(p[i] + 1,v[i],1,1,N);
65         for(int i = 1; i <= N; ++i){
66             if(i != 1) printf(" ");
67             printf("%d",ans[i]);
68         }
69         puts("");
70     }
71     return 0;
72 }

 

posted @ 2014-10-01 20:46  Naturain  阅读(167)  评论(0编辑  收藏  举报