POJ 2828 Buy Tickets(排队问题,线段树应用)
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(排队问题,线段树应用)的更多相关文章
- poj 2828 Buy Tickets 【线段树点更新】
题目:id=2828" target="_blank">poj 2828 Buy Tickets 题意:有n个人排队,每一个人有一个价值和要插的位置,然后当要插的位 ...
- POJ 2828 Buy Tickets(线段树 树状数组/单点更新)
题目链接: 传送门 Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Description Railway tickets were d ...
- POJ - 2828 Buy Tickets(线段树单点更新)
http://poj.org/problem?id=2828 题意 排队买票,依次给出当前人要插队的位置,每个人有个编号,然后问你最后整个的序列是什么? 分析 最后一个人的要插入的位置是确定的,所以逆 ...
- poj 2828 buy Tickets 用线段树模拟带插入的队列
Buy Tickets Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2 ...
- poj 2828 Buy Tickets【线段树单点更新】【逆序输入】
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 16273 Accepted: 8098 Desc ...
- poj 2828 Buy Tickets (线段树 单节点 查询位置更新)
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 15533 Accepted: 7759 Desc ...
- POJ 2828 Buy Tickets (线段树 单点更新 变形)
题目链接 题意:有N个人排队,给出各个人想插队的位置和标识,要求输出最后的序列. 分析:因为之前的序列会因为插队而变化,如果直接算时间复杂度很高,所以可以用 线段树逆序插入,把序列都插到最后一层,le ...
- POJ 2828 Buy Tickets (线段树 || 树状数组)
题目大意 一些小朋友在排队,每次来一个人,第i个人会插到第x个人的后面.权值为y.保证x∈[0,i-1]. 按照最后的队伍顺序,依次输出每个人的权值. 解题分析 好气吖.本来是在做splay练习,然后 ...
- poj 2828 Buy Tickets【线段树 单点更新】
倒着插,先不理解意思,后来看一篇题解说模拟一下 手动模拟一下就好理解了----- 不过话说一直写挫---一直改啊----- 好心塞------ #include <cstdio> #inc ...
- 【POJ】2828 Buy Tickets(线段树+特殊的技巧/splay)
http://poj.org/problem?id=2828 一开始敲了个splay,直接模拟. tle了.. 常数太大.. 好吧,说是用线段树.. 而且思想很拽.. (貌似很久以前写过貌似的,,) ...
随机推荐
- windows服务的创建、安装和调试
1.创建 windows服务 项目 文件 -> 新建项目 -> 已安装的模板 -> Visual C# -> windows ,在右侧窗口选择"windows 服 ...
- [置顶] ※数据结构※→☆线性表结构(list)☆============双向链表结构(list double)(三)
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点. ~~~~~~~~~~~~ ...
- KISSY 库 demo
KISSY 是由淘宝前端project师们发起创建的一个开源 JS 类库. 它遵循的原则是 小巧灵活.简洁有用.愉悦编码.快乐开发. DEMO: <!DOCTYPE html> <h ...
- sql语句中 limi的用法
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset 使用查询语句时需要返回前几条或者中间的某几行数据时可以用到limit 例如 ...
- notepad扩展搜索,正则搜索
Dos和windows采用回车+换行CR/LF表示下一行, 0d 0a 两个字节表示而UNIX/Linux采用’\n’换行符LF表示下一行(ASCII代码是10),0a一个字节表示MAC OS系统则采 ...
- art patchoat
Add patchoat tool to Art. Add a new executable called patchoat to art. This tool takes alreadycompil ...
- Android平台调用Web Service:螺纹的引入
连接文本 剩下的问题 MainActivity的onCreate方法中假设没有有这段代码: // 强制在UI线程中操作 StrictMode.setThreadPolicy(new StrictMod ...
- .net读取异步Post的内容
//读取微信Post过来的XML内容 byte[] input = HttpContext.Current.Request.BinaryRead(HttpContext ...
- 在Eclipse在使用JUnit4单元测试(0基础知识)
自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,须要写成千上万个方法或函数.这些函数的功能可能非常强大,但我们在 ...
- ASP.NET WebForm / MVC 源码分析
浏览器 Url:https//localhost:6565/Home/Index ,https//localhost:6565/WebForm1.aspx,请求服务器(构建请求报文,并且将请求报文发送 ...