POJ 2828 Buy Tickets 线段树 + 思维
2016-10-26 21:00
489 查看
题目:
http://poj.org/problem?id=2828题意:
有n个人来排队,每次来一个人都会插到当前队伍中某个人的后面,输出最后的排队序列思路:
思维题。可以发现,每个人最后的位置,只跟他之后来插队的人有关,于是可以逆序求解,具体可用线段树#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> const int N = 200010; struct node { int l, r, val, siz; }g[N*4]; int n; int a , b ; void push_up(int k) { g[k].siz = g[k<<1].siz + g[k<<1|1].siz; } void build(int l, int r, int k) { g[k].l = l, g[k].r = r, g[k].siz = r - l + 1; if(l == r) return; int mid = (l + r) >> 1; build(l, mid, k << 1); build(mid + 1, r, k << 1|1); //push_up(k); } void update(int pos, int val, int k) { if(g[k].l == g[k].r) { g[k].val = val; g[k].siz--; return; } if(pos <= g[k<<1].siz) update(pos, val, k << 1); else update(pos - g[k<<1].siz, val, k << 1|1); push_up(k); } void query(int k) { if(g[k].l == g[k].r) { if(g[k].l == n) printf("%d\n", g[k].val); else printf("%d ", g[k].val); return; } query(k << 1); query(k << 1|1); } int main() { while(~ scanf("%d", &n)) { build(1, n, 1); for(int i = 1; i <= n; i++) scanf("%d%d", &a[i], &b[i]); for(int i = n; i >= 1; i--) update(a[i]+1, b[i], 1); query(1); } return 0; }
相关文章推荐
- POJ 2828 Buy Tickets(排队问题,线段树应用)
- 线段树(单点更新) POJ 2828 Buy tickets
- POJ 2828 Buy Tickets (线段树 单点更新-查找第k大元素)
- POJ 2828--Buy Tickets(线段树)
- POJ 2828 Buy Tickets 线段树 单点修改记录状态
- POJ 2828 Buy Tickets 线段树入门(建树稍微有点抽象)
- poj 2828 Buy Tickets 线段树单点更新
- POJ 2828 Buy Tickets(线段树)
- poj_2828 Buy Tickets(线段树)
- poj 2828 Buy Tickets 【线段树点更新】
- POJ 2828 Buy Tickets 结构体型的线段树 学习ing
- POJ 2828 - Buy Tickets 【线段树】
- POJ2828 Buy Tickets 线段树
- poj 2828 Buy Tickets 【线段树】【逆序插入 + 单点更新 + 区间求和】
- POJ 2828 Buy Tickets(排队问题,线段树应用)
- POJ_2828_Buy Tickets_线段树、机智
- POJ 2828 Buy Tickets (线段树)
- (中等) POJ 2828 Buy Tickets , 逆序+线段树。
- POJ 2828 Buy Tickets(线段树)
- POJ - 2828 Buy Tickets(线段树单点更新)