您的位置:首页 > 其它

poj2828 Buy Tickets

2015-09-28 17:31 375 查看
维护一个动态序列。

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

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

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

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

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

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

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

#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson (u << 1)
#define rson (u << 1 | 1)
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
//using namespace std;
const int maxn = 2e5 + 10;

struct Seg{
int l, r, maxi, mini;
int lazy;
}seg[maxn << 2];
int n;
int b[maxn], c[maxn];

void push_up(int u){
seg[u].maxi = max(seg[lson].maxi, seg[rson].maxi);
seg[u].mini = min(seg[lson].mini, seg[rson].mini);
}

void build(int u, int l, int r){
seg[u].l = l, seg[u].r = r, seg[u].lazy = 0;
if(r - l < 2){
seg[u].maxi = seg[u].mini = l;
return;
}
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid, r);
push_up(u);
}

int ans[maxn];

void push_down(int u){
if(seg[u].r - seg[u].l > 1 && seg[u].lazy != 0){
seg[lson].maxi -= seg[u].lazy, seg[rson].maxi -= seg[u].lazy;
seg[lson].mini -= seg[u].lazy, seg[rson].mini -= seg[u].lazy;
seg[lson].lazy += seg[u].lazy, seg[rson].lazy += seg[u].lazy;
seg[u].lazy = 0;
}
}

void update(int u, int l, int r, int L, int R){
if(L == l && r == R){
seg[u].maxi--, seg[u].mini--;
seg[u].lazy++;
return;
}
push_down(u);
int mid = (l + r) >> 1;
if(R <= mid) update(lson, l, mid, L, R);
else if(L >= mid) update(rson, mid, r, L, R);
else{
update(lson, l, mid, L, mid);
update(rson, mid, r, mid, R);
}
push_up(u);
}

int query(int u, int l, int r, int v){
if(r - l < 2) return l;
push_down(u);
int mid = (l + r) >> 1;
if(v >= seg[lson].mini && seg[lson].maxi >= v) return query(lson, l, mid, v);
return query(rson, mid, r, v);
}

int main(){
freopen("in.txt", "r", stdin);
while(~scanf("%d", &n)){
for(int i = 1; i <= n; i++){
scanf("%d%d", &b[i], &c[i]);
}
build(1, 1, n + 1);
for(int i = n; i >= 1; i--){
//find the position to insert
int pos = query(1, 1, n + 1, b[i] + 1);
ans[pos] = c[i];
update(1, 1, n + 1, pos, n + 1);
}
printf("%d", ans[1]);
for(int i = 2; i <= n; i++) printf(" %d", ans[i]);
putchar('\n');
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: