poj2828 Buy Tickets

维护一个动态序列。

给定前k的数的一个排列 σ(1)... σ(k),表示第k个人占据当前序列的第σ(k)位置。

考虑将第k+1个人插入到原序列的第p位(其中p ≤ k),后面的人向后各移动一位。

线段树的叶子节点表示静态序列此处位置对应当前动态序列的位置序号。

从后往前不断寻找合适位置再更新即可。

对于重复元素只有第一个是有效的。

不过g++还是tle了,c++能过。

 

http://poj.org/problem?id=2828

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define lson (u << 1)
 5 #define rson (u << 1 | 1)
 6 #define max(a, b) (a > b ? a : b)
 7 #define min(a, b) (a < b ? a : b)
 8 //using namespace std;
 9 const int maxn = 2e5 + 10;
10 
11 struct Seg{
12     int l, r, maxi, mini;
13     int lazy;
14 }seg[maxn << 2];
15 int n;
16 int b[maxn], c[maxn];
17 
18 void push_up(int u){
19     seg[u].maxi = max(seg[lson].maxi, seg[rson].maxi);
20     seg[u].mini = min(seg[lson].mini, seg[rson].mini);
21 }
22 
23 void build(int u, int l, int r){
24     seg[u].l = l, seg[u].r = r, seg[u].lazy = 0;
25     if(r - l < 2){
26         seg[u].maxi = seg[u].mini = l;
27         return;
28     }
29     int mid = (l + r) >> 1;
30     build(lson, l, mid);
31     build(rson, mid, r);
32     push_up(u);
33 }
34 
35 int ans[maxn];
36 
37 void push_down(int u){
38     if(seg[u].r - seg[u].l > 1 && seg[u].lazy != 0){
39         seg[lson].maxi -= seg[u].lazy, seg[rson].maxi -= seg[u].lazy;
40         seg[lson].mini -= seg[u].lazy, seg[rson].mini -= seg[u].lazy;
41         seg[lson].lazy += seg[u].lazy, seg[rson].lazy += seg[u].lazy;
42         seg[u].lazy = 0;
43     }
44 }
45 
46 void update(int u, int l, int r, int L, int R){
47     if(L == l && r == R){
48         seg[u].maxi--, seg[u].mini--;
49         seg[u].lazy++;
50         return;
51     }
52     push_down(u);
53     int mid = (l + r) >> 1;
54     if(R <= mid) update(lson, l, mid, L, R);
55     else if(L >= mid) update(rson, mid, r, L, R);
56     else{
57         update(lson, l, mid, L, mid);
58         update(rson, mid, r, mid, R);
59     }
60     push_up(u);
61 }
62 
63 int query(int u, int l, int r, int v){
64     if(r - l < 2) return l;
65     push_down(u);
66     int mid = (l + r) >> 1;
67     if(v >= seg[lson].mini && seg[lson].maxi >= v) return query(lson, l, mid, v);
68     return query(rson, mid, r, v);
69 }
70 
71 int main(){
72     freopen("in.txt", "r", stdin);
73     while(~scanf("%d", &n)){
74         for(int i = 1; i <= n; i++){
75             scanf("%d%d", &b[i], &c[i]);
76         }
77         build(1, 1, n + 1);
78         for(int i = n; i >= 1; i--){
79             //find the position to insert
80             int pos = query(1, 1, n + 1, b[i] + 1);
81             ans[pos] = c[i];
82             update(1, 1, n + 1, pos, n + 1);
83         }
84         printf("%d", ans[1]);
85         for(int i = 2; i <= n; i++) printf(" %d", ans[i]);
86         putchar('\n');
87     }
88     return 0;
89 }
View Code

 

posted @ 2015-09-28 17:31  astoninfer  阅读(99)  评论(0编辑  收藏  举报