【HDU4967】Handling the Past
2024-08-25 15:32:10
题意
模拟栈操作。有三种操作push,pop,peak分别代表从栈顶压入元素,删除栈顶元素,查询栈顶元素。但是,每个操作会给出一个时间戳,要求操作必须要按照时间戳来进行。但是对于每个peak必须马上给出查询结果。其中n<=50000,xi,ti<=1e9
分析
讲真,这种题必须结合样例才能明白让干嘛。如果暴力的话,对于每个peak的时间复杂度都是O(n)。所以我们想到了线段树。
1.因为t的值很大,所以我们要首先将t离散化(我因为离散化写丑了一开始还T了好几发)
2.将每个push的t和x对应的记录下来
3.对于每个操作push,我们在t的位置插入1,对于每个pop操作,我们在t的位置插入-1。对于每个peak操作,我们找到t左边的第一个t1,符合sum(t1 to t)>0,这时候和t1对应的x值就是答案。
思路是很好想的,然后就是操作3该怎么通过线段树来维护?
我们通过线段树来维护一个区间和,和一个最大后缀和,然后对于没个peak查询,所有从1到t的线段树的结点,从右往左找,如果加上当前结点的最大后缀和大于0的话,这个答案就一定在这个节点内,否则加上这个结点的区间和继续往左找。这里可以结合代码进行理解。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map> using namespace std;
const int maxn=+;
struct Ope{
string name;
int t,a;
}ope[maxn];
int n,kase;
int V[maxn],M[maxn];
int sumv[*maxn],max_suff[*maxn];
int v,x;
void maintain(int o){
sumv[o]=sumv[*o]+sumv[*o+];
max_suff[o]=max(max_suff[*o+],sumv[*o+]+max_suff[*o]);
}
void update(int o,int L,int R){
if(L==R){
sumv[o]+=x;
max_suff[o]+=x;
return ;
}
int M=L+(R-L)/;
if(v<=M)update(*o,L,M);
if(v>M)update(*o+,M+,R);
maintain(o);
return;
}
int tot,ans;
int ql,qr;
void solve(int o,int L,int R){
if(L==R){
ans=L;
return;
}
int M=L+(R-L)/;
if(tot+max_suff[*o+]>)
return solve(*o+,M+,R);
tot+=sumv[*o+];
return solve(*o,L,M);
}
void query(int o,int L,int R){
if(ans!=-)
return;
if(ql<=L&&qr>=R){
if(tot+max_suff[o]>){
solve(o,L,R);
}
else tot+=sumv[o];
return;
}
int M=L+(R-L)/;
if(M<qr)
query(*o+,M+,R);
if(M>=ql)
query(*o,L,M);
return;
}
int main(){
kase=;
while(scanf("%d",&n)!=EOF&&n){
printf("Case #%d:\n",++kase);
for(int i=;i<=n;i++){
cin>>ope[i].name;
if(ope[i].name=="push"){
scanf("%d%d",&ope[i].a,&ope[i].t);
}
if(ope[i].name=="pop"||ope[i].name=="peak"){
scanf("%d",&ope[i].t);
}
V[i]=ope[i].t;
}
sort(V+,V++n);
for(int i=;i<=n;i++){
if(ope[i].name=="push"){
int tt=lower_bound(V+,V++n,ope[i].t)-V;
M[tt]=ope[i].a;
}
}
/* for(int i=1;i<=n;i++){
int tt=lower_bound(V+1,V+1+n,ope[i].t)-V;
cout<<tt<<endl;
}*/ memset(sumv,,sizeof(sumv));
memset(max_suff,,sizeof(max_suff)); for(int i=;i<=n;i++){
if(ope[i].name=="push"){
v=lower_bound(V+,V++n,ope[i].t)-V;
x=;
update(,,n);
}
else if(ope[i].name=="pop"){
v=lower_bound(V+,V++n,ope[i].t)-V;
x=-;
update(,,n);
}
else{
ql=,qr=lower_bound(V+,V++n,ope[i].t)-V;
tot=,ans=-;
query(,,n);
printf("%d\n",ans==-?-:M[ans]);
}
}
}
return ;
}
最新文章
- 在PHP语言中使用JSON和将json还原成数组
- Android开发常见问题小结
- VC++ CStatic控件背景透明且改变其文本时,文字重叠解决方法
- JavaScript 入门 (1)
- const char * char * const
- undefined function mysql_connect()解决方法
- @Param注解在mybatis中的使用以及传入参数的几种方式(转)
- Sqli-labs less 28
- 当函数没有return时错误
- hadoop2.0安装和配置
- CentOS 5 64bit 编译安装MySQL报错
- iOS之断点下载,使用NSURLSession简单封装
- spring boot / cloud (三) 集成springfox-swagger2构建在线API文档
- 多路复用(select、epoll)实现tcp服务
- (54)Wangdao.com第七天_JavaScript 运算符
- count性能
- Mysql知识点个人整理
- OpenGL Compute Shader靠谱例子及读取二进制Shader,SPIR-V
- django基础(一)
- Jmeter分布测试
热门文章
- [MEF]第04篇 MEF的多部件导入(ImportMany)和目录服务
- 【常见Web应用安全问题】---4、Directory traversal
- 轻量级封装DbUtils&;Mybatis之二Dbutils
- NETCTOSS - 中国电信运营支持系统-网络版_V-1.0
- linux mount / umount 命令的基本用法 及 开机自动挂载
- error: src refspec master does not match any.
- CRUD
- nginx限制请求之一:(ngx_http_limit_conn_module)模块
- Log4j配置详解之log4j.xml
- 项目中Map端内存占用的分析