博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2828 Buy Tickets(排队问题,线段树应用)
阅读量:5899 次
发布时间:2019-06-19

本文共 2298 字,大约阅读时间需要 7 分钟。

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

ACM

题目地址:

题意: 

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

分析: 

也是一道非常巧妙的题目。 
刚開始天真的以为sort一下即可了。wa了一发后发现我错了... 
原来能够非常巧妙的用线段树做。因为某个人想要插入posi位置,插入后他就在posi位置上了,可是可能其它人会插到他前面来,他的位置就会变成[在他后面且插在他位置及曾经的人数]+posi了。 
假设这样就開始求了,当然用线段树就能够做了,就跟求逆序数对一样。 
可是我们能够反着来考虑,仅仅要从后面開始站,如果后面的人都已经站在正确的位置上了,那么到那个人站的时候,如今的位置上已经都是后面的那些人了,仅仅要数posi个空格,那那个人站的位置能确定了。确定之后就能够求下一个了,所以这个前提和结论都成立了。

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

线段树的话跟求和线段树一样,初始化时所有初始化为1,然后查找的时候能够“二分”查找,巧妙地找到须要的位置,详细见代码,尽管代码非常挫。 
代码用了输入输出外挂来提速,没加也能过的,请无视。

代码

/**  Author:      illuz 
* Blog: http://blog.csdn.net/hcbbt* File: 2828.cpp* Create Date: 2014-08-05 20:16:28* Descripton: */#include
#include
#include
#include
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 versionstruct 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;}
你可能感兴趣的文章
扫描(一)
查看>>
MySQLDump在使用之前一定要想到的事情 [转载]
查看>>
PIE SDK矢量数据的读取
查看>>
两种方式分别改变alertdialog的宽和高
查看>>
TextView-setCompondDrawables用法
查看>>
淘宝Hadoop集群的概况
查看>>
Centos7安装rabbitmq server 3.6.0
查看>>
关于eclipse的ADT(插件)对xml的android:text属性检查修改
查看>>
iostat命令学习
查看>>
SQL 三种分页方式
查看>>
查看linux是ubuntu还是centos
查看>>
html video的url更新,自动清缓存
查看>>
IOS Xib使用——为控制器添加Xib文件
查看>>
CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙步骤
查看>>
react 取消 eslint
查看>>
【11】ajax请求后台接口数据与返回值处理js写法
查看>>
Python菜鸟之路:Jquery Ajax的使用
查看>>
LeetCode算法题-Maximum Depth of Binary Tree
查看>>
sha1withRSA算法
查看>>
Vim和操作系统剪贴板交互
查看>>