POJ 2828 Buy Tickets 题解&代码
2015-12-03 19:43
369 查看
题目大意:对于每组数据,给出一个空队列,有m次插入,每次插入都将在队列的第pos[i]处插入一个值val[i],输出队列最后的状态。
思路:
在第pos[i]处插入一个元素,则第pos[i]处后的所有元素都将向后移动一位,看起来是平均每次插入需要n次操作。
但是我们可以看出,对每次插入来说,本次插入结束后本次所插入的元素位置一定会是pos[i]+1,那么与其先插入可能会需要向后移动的元素,不如从最后一个被插入的元素开始向一个[0,m]的空区间插入元素,这样每一次插入都不会对已经记录的状态产生影响。
这样的话,可以将这道题转换成线段树来做,用一个s标记统计区间内被插入的元素数,用v数组记录区间上的单点被插入值。
第i个元素的位置应当是从0开始的空位置中的第pos[i]个,我们可以用(r-l+1)-s[o]来统计区间编号为o的区间内有多少个空位置,如果(r-l+1)-s[o]>pos[i],那么这个区间包含该元素应该被插入的区间。
对代码能力要求不高,注意判定的细节和线段树的特性,基本上过样例就说明AC…我这种手残大约40min就调过了
**代码中的边界判定与思路中所说有微小区别
思路:
在第pos[i]处插入一个元素,则第pos[i]处后的所有元素都将向后移动一位,看起来是平均每次插入需要n次操作。
但是我们可以看出,对每次插入来说,本次插入结束后本次所插入的元素位置一定会是pos[i]+1,那么与其先插入可能会需要向后移动的元素,不如从最后一个被插入的元素开始向一个[0,m]的空区间插入元素,这样每一次插入都不会对已经记录的状态产生影响。
这样的话,可以将这道题转换成线段树来做,用一个s标记统计区间内被插入的元素数,用v数组记录区间上的单点被插入值。
第i个元素的位置应当是从0开始的空位置中的第pos[i]个,我们可以用(r-l+1)-s[o]来统计区间编号为o的区间内有多少个空位置,如果(r-l+1)-s[o]>pos[i],那么这个区间包含该元素应该被插入的区间。
对代码能力要求不高,注意判定的细节和线段树的特性,基本上过样例就说明AC…我这种手残大约40min就调过了
**代码中的边界判定与思路中所说有微小区别
#include<iostream> #include<stdio.h> #define lson (o<<1) #define rson ((o<<1)|1) using namespace std; const int maxn=200005; bool flag,f; int n,p[maxn],val[maxn],v[maxn],s[maxn*4]; void build_tree(int o,int l,int r) { s[o]=0; if(l==r) { v[l]=0; return; } int mid=(l+r)/2; build_tree(lson,l,mid); build_tree(rson,mid+1,r); } void maintain(int o,int l,int r) { s[o]=s[lson]+s[rson]; } void add_tree(int o,int l,int r,int z,int x) { if(l==r) { if(s[o])return; v[l]=x; s[o]=1; f=true; return; } int mid=(l+r)/2; if(mid>=z && z<=(mid-l+1)-s[lson])add_tree(lson,l,mid,z,x); else { z-=(mid-l+1)-s[lson]; add_tree(rson,mid+1,r,z,x); } maintain(o,l,r); } void print_tree(int o,int l,int r) { if(l==r) { if(flag)printf(" %d",v[l]-1); else printf("%d",v[l]-1); flag=true; return; } int mid=(l+r)/2; print_tree(lson,l,mid); print_tree(rson,mid+1,r); } int main(void) { while(cin>>n) { flag=false; build_tree(1,1,n); for(int i=1;i<=n;i++) { scanf("%d%d",&p[i],&val[i]); p[i]++;val[i]++; } for(int i=n;i>0;i--) { f=false; add_tree(1,1,n,p[i],val[i]); } print_tree(1,1,n); printf("\n"); } return 0; }
相关文章推荐
- java 利用dom4j 解析XML文件
- 使用Spring JdbcTemplate操作数据库
- ubuntu下opencv + qt 开发环境的搭建
- rdm代码网址
- 浅谈Java中的Set、List、Map的区别
- C#语法基础巩固
- JAVA框架——Maven
- 趣学Python-教孩子学编程--第十一章
- Java集合---ArrayList的实现原理
- (手册)从 ASP .NET 进行 Active Directory 域服务身份验证
- Asp.net读取AD域信息的方法(一)
- Spring aop 原始的工作原理的理解
- c语言基础知识
- 关于spring 3.2 @scheduled cron的
- Delphi 函数指针(三大好处:灵活,委托的本质,回调机制),还可把函数指针当参数传入
- struts2默认action
- ASP.net 学习路线(详细)
- 1040、有几个PAT
- Python程序运行时间计算
- Java,C++,C语言的文件输入输出方式