POJ 2828 Buy Tickets(排队问题,线段树应用)

ACM

题目地址:POJ 2828 Buy Tickets

题意: 

排队买票时候插队。 

给出一些数对,分别代表某个人的想要插入的位置Pos_i和他的Val_i,求出最后的队列的val顺序。

分析: 

也是一道非常巧妙的题目。 

刚開始天真的以为sort一下即可了。wa了一发后发现我错了... 

原来能够非常巧妙的用线段树做。因为某个人想要插入posi位置,插入后他就在posi位置上了,可是可能其它人会插到他前面来,他的位置就会变成[在他后面且插在他位置及曾经的人数]+posi了。 

假设这样就開始求了,当然用线段树就能够做了,就跟求逆序数对一样。 

可是我们能够反着来考虑,仅仅要从后面開始站,如果后面的人都已经站在正确的位置上了,那么到那个人站的时候,如今的位置上已经都是后面的那些人了,仅仅要数posi个空格,那那个人站的位置能确定了。确定之后就能够求下一个了,所以这个前提和结论都成立了。

所以我们仅仅要从后面人站起,数posi个空格站上去即可了。 

线段树的话跟求和线段树一样,初始化时所有初始化为1,然后查找的时候能够“二分”查找,巧妙地找到须要的位置,详细见代码,尽管代码非常挫。 

代码用了输入输出外挂来提速,没加也能过的,请无视。

代码:

/*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.csdn.net/hcbbt
* File: 2828.cpp
* Create Date: 2014-08-05 20:16:28
* Descripton:
*/ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define lson(x) ((x) << 1)
#define rson(x) ((x) << 1 | 1) typedef long long ll; const int N = 200000;
const int ROOT = 1; // below is sement point updated version
struct seg {
ll w;
}; struct segment_tree {
seg node[N << 2]; void update(int pos) {
node[pos].w = node[lson(pos)].w + node[rson(pos)].w;
} void build(int l, int r, int pos) {
if (l == r) {
node[pos].w = 1;
return;
}
int m = (l + r) >> 1;
build(l, m, lson(pos));
build(m + 1, r, rson(pos));
update(pos);
} int remove(int l, int r, int pos, ll x) { // 删掉并查询
if (l == r) {
node[pos].w = 0;
return l;
}
int m = (l + r) >> 1;
int res;
if (x < node[lson(pos)].w) // 再此二分查找
res = remove(l, m, lson(pos), x);
else
res = remove(m + 1, r, rson(pos), x - node[lson(pos)].w);
update(pos);
return res;
}
} sgm; int Scan() {
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-')
flag = 1;
else if(ch >= '0' && ch <= '9')
res = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
} void Out(int a) {
if(a > 9)
Out(a / 10);
putchar(a % 10 + '0');
} int a[2][N], n;
int ans[N]; int main() {
while (~scanf("%d", &n)) {
repf (i, 0, n - 1) {
a[0][i] = Scan();
a[1][i] = Scan();
}
sgm.build(1, n, ROOT);
for (int i = n - 1; i >= 0; i--) {
ans[sgm.remove(1, n, ROOT, a[0][i])] = a[1][i];
}
repf (i, 1, n) {
if (i != 1)
printf(" ");
Out(ans[i]);
}
printf("\n");
}
return 0;
}

POJ 2828 Buy Tickets(排队问题,线段树应用)的更多相关文章

  1. poj 2828 Buy Tickets 【线段树点更新】

    题目:id=2828" target="_blank">poj 2828 Buy Tickets 题意:有n个人排队,每一个人有一个价值和要插的位置,然后当要插的位 ...

  2. POJ 2828 Buy Tickets(线段树 树状数组/单点更新)

    题目链接: 传送门 Buy Tickets Time Limit: 4000MS     Memory Limit: 65536K Description Railway tickets were d ...

  3. POJ - 2828 Buy Tickets(线段树单点更新)

    http://poj.org/problem?id=2828 题意 排队买票,依次给出当前人要插队的位置,每个人有个编号,然后问你最后整个的序列是什么? 分析 最后一个人的要插入的位置是确定的,所以逆 ...

  4. poj 2828 buy Tickets 用线段树模拟带插入的队列

    Buy Tickets Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2 ...

  5. poj 2828 Buy Tickets【线段树单点更新】【逆序输入】

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 16273   Accepted: 8098 Desc ...

  6. poj 2828 Buy Tickets (线段树 单节点 查询位置更新)

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 15533   Accepted: 7759 Desc ...

  7. POJ 2828 Buy Tickets (线段树 单点更新 变形)

    题目链接 题意:有N个人排队,给出各个人想插队的位置和标识,要求输出最后的序列. 分析:因为之前的序列会因为插队而变化,如果直接算时间复杂度很高,所以可以用 线段树逆序插入,把序列都插到最后一层,le ...

  8. POJ 2828 Buy Tickets (线段树 || 树状数组)

    题目大意 一些小朋友在排队,每次来一个人,第i个人会插到第x个人的后面.权值为y.保证x∈[0,i-1]. 按照最后的队伍顺序,依次输出每个人的权值. 解题分析 好气吖.本来是在做splay练习,然后 ...

  9. poj 2828 Buy Tickets【线段树 单点更新】

    倒着插,先不理解意思,后来看一篇题解说模拟一下 手动模拟一下就好理解了----- 不过话说一直写挫---一直改啊----- 好心塞------ #include <cstdio> #inc ...

  10. 【POJ】2828 Buy Tickets(线段树+特殊的技巧/splay)

    http://poj.org/problem?id=2828 一开始敲了个splay,直接模拟. tle了.. 常数太大.. 好吧,说是用线段树.. 而且思想很拽.. (貌似很久以前写过貌似的,,) ...

随机推荐

  1. Hdu 4539 【状态DP】.cpp

    题意: 一个炮兵可以攻打和他之间曼哈顿距离为2的士兵,给出你一块n*m的战场,告诉你哪些地方可以站人哪些地方不可以,问你最多可以安放多少个士兵? n <= 100, m <= 10 思路: ...

  2. 基于 Groovy 的自动化构建工具 Gradle 入门(转)

    本人工作之初没有使用自动化构建,后来敏捷了,开始使用 Ant - 完全面向过程的定义步骤,不进行依赖管理.再发展到 Maven,面向对象的方式管理工程,有了依赖的管理,JAR 包统一从中央仓库获得,保 ...

  3. Set vs. Set<?>(转)

    You may know that an unbounded wildcard Set<?> can hold elements of any type, and a raw type S ...

  4. String ,StringBuffer,StringBuilder精髓比較

    1. 在运行速度方面的比較:StringBuilder > StringBuffer > String 2. StringBuffer与StringBuilder.他们是字符串变量,是可改 ...

  5. SharePoint采用BCS开发第一个应用程序(两)

    SharePoint采用BCS开发第一个应用程序(两) 创建外部数据源 在本章中,我们使用AdventureWorksLT2008 SQL Server数据库作为外部数据源.下图显示了表SalesLT ...

  6. EF 批量 循环删除

    var list = db.T_xAppRecord.Where(u => u.Id == 1).ToList(); //2.0 遍历集合,将 要删除的 对象 的代理对象的State 设置为 D ...

  7. POJThe Doors AND NYIST 有趣的问题

    POJThe Doors AND NYIST 有趣的问题 题目链接:pid=227" target="_blank">Click Here~ 题目分析: 给你横纵坐 ...

  8. POJ 1276  Cash Machine(多重背包)

    Cash Machine Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24132 Accepted: 8446 Descrip ...

  9. 内网port映射具体解释(花生壳)

    关于怎样建立服务器的解答. 一.花生壳的作用 首先,我们先来了解一下花生壳的究竟有什么作用.由于ADSL每次拨号上网所获得的IP地址每次都是不同的,花生壳起到的作用就是方便用户訪问我们的server( ...

  10. 二分图行列匹配---> hdu2119,hdu1498

    hdu2119 题意:给定一个矩形方格,每个格子里面的数字是0或者1,每次操作可以把一整行或列的1变成0,问最少多少次操作能将1全部变为0 一次可以消除某一行或者某一列的1但是可以这么想,最多有多少个 ...