题意:给你n组操作,分别为压栈,出栈,询问栈顶元素。每一组操作有一个时间戳,每次询问栈顶的元素的操作询问的是在他之前出现的操作,而且时间戳小于它的情况。题目中不会出现栈为空而且出栈的情况。

例如:

push 100 1

peak 6

push 200 5

询问的结果是100。

思路:先把时间戳离散化,我们把压栈看成在这个操作所在的时间+1,出栈看成-1,那么询问操作可以看成从询问的时间开始,找一段最短的后缀,并且后缀和大于0。所以我们在线段树中维护区间和和后缀和,查询的时候先搜索右半区间,如果右半区间的后缀和小于0,那把右半区间的和加上,再去查询左半区间。

代码:

#include <bits/stdc++.h>
#define ls(x) (x << 1)
#define rs(x) ((x << 1) | 1)
using namespace std;
const int maxn = 50010;
int ans;
struct op {
int id, time, val;
}; op a[maxn];
int mp1[maxn], mp2[maxn], b[maxn];
struct SegementTree {
int psum, sum;
}; SegementTree tr[maxn * 4]; void maintain(int o) {
tr[o].sum = tr[ls(o)].sum + tr[rs(o)].sum;
tr[o].psum = max(tr[rs(o)].psum, tr[rs(o)].sum + tr[ls(o)].psum);
} void init(int o, int l, int r) {
if(l == r) {
tr[o].sum = tr[o].psum = 0;
return;
}
int mid = (l + r) >> 1;
init(ls(o), l ,mid);
init(rs(o), mid + 1, r);
maintain(o);
} void insert(int o, int l, int r, int pos, int val) {
if(l == r) {
tr[o].sum += val;
tr[o].psum += val;
return;
}
int mid = (l + r) >> 1;
if(pos <= mid) insert(ls(o), l, mid, pos, val);
else insert(rs(o), mid + 1, r, pos, val);
maintain(o);
} int query(int o, int l, int r, int ql, int qr, int now) {
int tmp = 0;
if(ql <= l && r <= qr) {
if(tr[o].psum + now <= 0) return tr[o].sum;
else {
if(l == r) {
ans = l;
return tr[o].sum;
}
}
}
int mid = (l + r) >> 1;
if(qr > mid) tmp = query(rs(o), mid + 1, r, ql, qr, now);
if(ans != -1) return tmp;
tmp += query(ls(o), l, mid, ql, qr, now + tmp);
return tmp;
}
char s[10];
int main() {
int n, x, y, kase = 0;
while(~scanf("%d", &n) && n) {
init(1, 1, n);
for (int i = 1; i <= n; i++) {
scanf("%s", s + 1);
if(s[2] == 'u') {
scanf("%d%d", &x, &y);
a[i] = (op){1, y, x};
b[i] = y;
} else if(s[2] == 'o') {
scanf("%d", &x);
a[i] = (op){2, x, 0};
b[i] = x;
} else {
scanf("%d", &x);
a[i] = (op){3, x, 0};
b[i] = x;
}
}
sort(b + 1, b + 1 + n);
for (int i = 1; i <= n; i++) {
int pos = lower_bound(b + 1, b + 1 + n, a[i].time) - b;
mp1[pos] = i;
mp2[i] = pos;
}
printf("Case #%d:\n", ++kase);
for (int i = 1; i <= n; i++) {
if(a[i].id == 1)
insert(1, 1, n, mp2[i], 1);
else if(a[i].id == 2)
insert(1, 1, n, mp2[i], -1);
else {
ans = -1;
query(1, 1, n, 1, mp2[i], 0);
if(ans == -1) printf("-1\n");
else printf("%d\n", a[mp1[ans]].val);
}
}
}
}

  

线段树教做人系列(1)HDU4967 Handling the Past的更多相关文章

  1. Codeforces 719E (线段树教做人系列) 线段树维护矩阵

    题面简洁明了,一看就懂 做了这个题之后,才知道怎么用线段树维护递推式.递推式的递推过程可以看作两个矩阵相乘,假设矩阵A是初始值矩阵,矩阵B是变换矩阵,求第n项相当于把矩阵B乘了n - 1次. 那么我们 ...

  2. 线段树教做人系列(2)HDU 4867 XOR

    题意:给你一个数组a,长度为.有两种操作.一种是改变数组的某个元素的值,一种是满足某种条件的数组b有多少种.条件是:b[i] <= a[i],并且b[1]^b[2]...^b[n] = k的数组 ...

  3. Codeforces 1136E Nastya Hasn't Written a Legend (线段树教做人系列)

    题意:有一个数组a和一个数组k,数组a一直保持一个性质:a[i + 1] >= a[i] + k[i].有两种操作:1,给某个元素加上x,但是加上之后要保持数组a的性质.比如a[i]加上x之后, ...

  4. 线段树教做人系列(3) HDU 4913

    题意及思路看这篇博客就行了,讲得很详细. 下面是我自己的理解: 如果只有2,没有3的话,做法就很简单了,只需要对数组排个序,然后从小到大枚举最大的那个数.那么它对答案的贡献为(假设这个数排序后的位置是 ...

  5. hdu 4521 小明系列问题——小明序列 线段树+二分

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Pro ...

  6. 2018.07.08 hdu4521 小明系列问题——小明序列(线段树+简单dp)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Proble ...

  7. SPOJ GSS3 线段树系列1

    SPOJ GSS系列真是有毒啊! 立志刷完,把线段树搞完! 来自lydrainbowcat线段树上的一道例题.(所以解法参考了lyd老师) 题意翻译 n 个数, q 次操作 操作0 x y把 Ax 修 ...

  8. hdu 4521 小明系列问题——小明序列(线段树+DP或扩展成经典的LIS)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  9. [线段树系列] LCT打延迟标记的正确姿势

    这一篇博客将教你什么? 如何用LCT打延迟标记,LCT和线段树延迟标记间的关系,为什么延迟标记要这样打. ——正片开始—— 学习这一篇博客前,确保你会以下知识: Link-Cut-Tree,普通线段树 ...

随机推荐

  1. 删除rime输入法

    mac: 首先将输入法从偏好设置-键盘-输入源中去除,添加系统的输入法. 然后执行命令: $ killall Squirrel $ sudo rm -Rf "/Library/Input M ...

  2. ural 2018 The Debut Album(dp¥)

    2018. The Debut Album Time limit: 2.0 secondMemory limit: 64 MB Pop-group “Pink elephant” entered on ...

  3. BW里转换简单常用ABAP

    用户查看的是当时的物料折让,那你必然要给物料加个时间,才好区分.总是以现在最新的物料状态查看历史数据会出现问题.当时这个物料是折让的,现在不折让了.数据会有问题.加个DSO.做一个时间记录.读取系统时 ...

  4. 关于js序列化时间的方法

    var time = new Date(); var otime = getMyDate(time); //将毫秒转换成 年月日+时分秒 格式的 (1970-01-11 00:00:00) funct ...

  5. Express+Mongoose(MongoDB)+Vue2全栈微信商城项目全记录(二)

    用mogoose搭建restful测试接口 接着上一篇(Express+Mongoose(MongoDB)+Vue2全栈微信商城项目全记录(一))记录,今天单独搭建一个restful测试接口,和项目前 ...

  6. 每天一个linux命令(15):head命令

    版权声明更新:2017-05-19博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的mv命令. 2. ...

  7. [ Laravel 5.5 文档 ] 处理用户请求 —— HTTP 请求的过滤器:中间件

    [ Laravel 5.5 文档 ] 处理用户请求 —— HTTP 请求的过滤器:中间件 http://laravelacademy.org/post/7812.html 简介 中间件为过滤进入应用的 ...

  8. 异常:java.lang.IllegalStateException: No instances found of configserver(里面是一个微服务名)

    今天本地测试代码时出现了个异常,该异常出现的原因是:微服务启动的顺序出现了问题: 应该先启动本地eureka,然后在启动本地配置中心,然后在启动具体的微服务.

  9. setcookie函数的注意事项

    函数说明 bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $pat ...

  10. AJAX,jQuery Ajax和Deferred

    AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用,改善用户体验,实现无刷新效果的技术. 使用AJAX的优 ...