线段树教做人系列(1)HDU4967 Handling the Past
2024-09-06 06:08:38
题意:给你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);
}
}
}
}
最新文章
- NET中的Memcached.ClientLibrary使用详解
- Docker学习<;一>;--初体验Windows环境下安装
- QuartZ.net 常用配置说明
- ASP.NET Jquery+ajax上传文件(带进度条)
- DB天气app冲刺二阶段第三天
- JQ 让光标在文本框最末尾
- Walls POJ 1161
- hdu 2123
- NotImplementedException未实现该方法或操作
- Eclipse编译Arduino程序不能使用串口函数Serial.begin解决办法
- memcached 内存管理 分析(转)
- 解决VMware虚拟机不能上网的问题
- debug和release下PostThreadMessage的异同
- C语言描述栈的实现及操作(数组实现)
- 使用批处理文件(*.bat)同时打多个cmd窗口
- 禁用windows10自动更新
- C#复习笔记(4)--C#3:革新写代码的方式(查询表达式和LINQ to object(下))
- PHP(css样式)
- 使用阿里云cli管理安全组
- java动手动脑2
热门文章
- mac上获取手机的uuid
- python_安装python2.7.7和easy_install
- Agc007_C Pushing Balls
- 现网CPU飙高,Full GC告警
- New Year and Buggy Bot
- Python 2.7_爬取妹子图网站单页测试图片_20170114
- 「BJOI2018」链上二次求和
- bootstrap 多色表格
- 自定义mysql函数时报错,[Err] 1418 - This function has none of DETERMINISTIC......
- HDU4135(容斥原理)