题目链接:https://codeforces.com/contest/1089/problem/K

time limit per test: 2 seconds  memory limit per test: 512 megabytes

King Kog got annoyed of the usual laxity of his knights — they can break into his hall without prior notice! Thus, the King decided to build a reception with a queue where each knight chooses in advance the time when he will come and how long the visit will take. The knights are served in the order of the recorded time, but each knight has to wait until the visits of all the knights before him are finished.

Princess Keabeanie wants to see her father. However, she does not want to interrupt the knights so she joins the queue. Unfortunately, the knights change their minds very often — they can join the queue or cancel their visits. Please help the princess to understand how long she will have to wait until she sees her father if she enters the queue at the specified moments of time given the records at the reception.

Input
The first line of the input contains a single integer $q (1 \le q \le 3 \times 10^5)$ — the number of events. An event can be of three types: join, cancel, or query.

Join "+ $t$ $d$" $(1 \le t,d \le 10^6)$ — a new knight joins the queue, where $t$ is the time when the knight will come and $d$ is the duration of the visit.
Cancel "- $i$" $(1 \le i \le q)$ — the knight cancels the visit, where $i$ is the number (counted starting from one) of the corresponding join event in the list of all events.
Query "? $t$" $(1 \le t \le 10^6)$ — Keabeanie asks how long she will wait if she comes at the time $t$.
It is guaranteed that after each event there are no two knights with the same entrance time in the queue. Cancel events refer to the previous joins that were not cancelled yet.

Keabeanie can come at the same time as some knight, but Keabeanie is very polite and she will wait for the knight to pass.

Output
For each query write a separate line with the amount of time Keabeanie will have to wait.

Example
input
19
? 3
+ 2 2
? 3
? 4
+ 5 2
? 5
? 6
+ 1 2
? 2
? 3
? 4
? 5
? 6
? 7
? 9
- 8
? 2
? 3
? 6
output
0
1
0
2
1
3
2
1
2
1
0
0
2
1
1

题意:

国王构建了一个队列,骑士如果要来见国王,都要通过这个队列排队觐见国王。

给出三种操作,第一种代表骑士在 $t$ 时刻前来排队,它要跟国王商谈 $d$ 分钟(保证没有两个骑士同时到来)。

第二种代表第 $i$ 次操作,其所代表的那个来排队的骑士取消了这次觐见。

第三种代表公主在 $t$ 时刻也前来排队,询问她需要等多久才能就到父王(如果她和某个骑士同时到达,则她会礼让骑士)。

题解:

假设在某个时间区间 $[l,r]$ 内所有前来觐见的骑士,他们的 $d$ 之和为 $sum[l,r]$。

那么对于一次查询操作 $t$,必然有某个时刻 $i$ 来的这个骑士,其对应的 $i + sum[i][t]$ 正好就是公主要等到的那个时刻。

也就是说,只要求 $\max_{1 \le i \le t}(sum[i][t]+i) - t$ 即可。

因此,我们可以用线段树来进行维护,线段树节点有两个值 $sum$ 和 $mx$:$sum[l,r]$ 的意义如上所述;而 $mx[l,r]$ 则代表至少要到 $mx[l,r]$ 时刻才能见完 $[l,r]$ 区间内的所有骑士。

这两个值的维护方式如下,特别是 $mx$ 的维护是值得注意的:

node[rt].sum=node[ls].sum+node[rs].sum;
node[rt].mx=max(node[rs].mx,node[ls].mx+node[rs].sum);

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxq=3e5+;
const int maxt=1e6+;
int q;
pii et[maxq]; /********************************* Segment Tree - st *********************************/
#define ls (rt<<1)
#define rs (rt<<1|1)
struct Node{
int l,r;
ll sum,mx;
}node[*maxt];
void pushup(int rt)
{
node[rt].sum=node[ls].sum+node[rs].sum;
node[rt].mx=max(node[rs].mx,node[ls].mx+node[rs].sum);
}
void build(int rt,int l,int r)
{
node[rt].l=l; node[rt].r=r;
if(l==r)
{
node[rt].sum=, node[rt].mx=l;
return;
}
int mid=(l+r)/;
build(ls,l,mid);
build(rs,mid+,r);
pushup(rt);
}
void update(int rt,int pos,int val)
{
if(node[rt].l==node[rt].r)
{
node[rt].sum+=val;
node[rt].mx+=val;
return;
}
int mid=(node[rt].l+node[rt].r)/;
if(pos<=mid) update(ls,pos,val);
if(pos>mid) update(rs,pos,val);
pushup(rt);
}
ll ans;
void query(int rt,int t)
{
if(node[rt].r<=t)
{
ans=max(node[rt].mx,ans+node[rt].sum);
return;
}
int mid=(node[rt].l+node[rt].r)/;
query(ls,t);
if(mid<t) query(rs,t);
}
/********************************* Segment Tree - ed *********************************/ int main()
{
cin>>q;
build(,,);
for(int i=;i<=q;i++)
{
char op[]; scanf("%s",op);
if(op[]=='+')
{
int t,d; scanf("%d%d",&t,&d);
update(,t,d);
et[i]=make_pair(t,d);
}
if(op[]=='-')
{
int id; scanf("%d",&id);
update(,et[id].first,-et[id].second);
}
if(op[]=='?')
{
int t; scanf("%d",&t);
ans=; query(,t);
printf("%I64d\n",max(ans-t,0ll));
}
}
}

Codeforces 1089K - King Kog's Reception - [线段树][2018-2019 ICPC, NEERC, Northern Eurasia Finals Problem K]的更多相关文章

  1. Codeforces 1089E - Easy Chess - [DFS+特判][2018-2019 ICPC, NEERC, Northern Eurasia Finals Problem E]

    题目链接:https://codeforces.com/contest/1089/problem/E Elma is learning chess figures. She learned that ...

  2. 记第一场atcoder和codeforces 2018-2019 ICPC, NEERC, Northern Eurasia Finals Online Mirror

    下午连着两场比赛,爽. 首先是codeforses,我和一位dalao一起打的,结果考炸了,幸亏不计rating.. A Alice the Fan 这个就是记忆化搜索一下预处理,然后直接回答询问好了 ...

  3. [Codeforces 266E]More Queries to Array...(线段树+二项式定理)

    [Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...

  4. [Codeforces 280D]k-Maximum Subsequence Sum(线段树)

    [Codeforces 280D]k-Maximum Subsequence Sum(线段树) 题面 给出一个序列,序列里面的数有正有负,有两种操作 1.单点修改 2.区间查询,在区间中选出至多k个不 ...

  5. codeforces 1217E E. Sum Queries? (线段树

    codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...

  6. Codeforces 444 C. DZY Loves Colors (线段树+剪枝)

    题目链接:http://codeforces.com/contest/444/problem/C 给定一个长度为n的序列,初始时ai=i,vali=0(1≤i≤n).有两种操作: 将区间[L,R]的值 ...

  7. Codeforces Gym 100513F F. Ilya Muromets 线段树

    F. Ilya Muromets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/probl ...

  8. Codeforces 834D The Bakery【dp+线段树维护+lazy】

    D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...

  9. codeforces 1017C - Cloud Computing 权值线段树 差分 贪心

    https://codeforces.com/problemset/problem/1070/C 题意: 有很多活动,每个活动可以在天数为$[l,r]$时,提供$C$个价格为$P$的商品 现在从第一天 ...

随机推荐

  1. linux服务器挂掉自动重启脚本(转)

    实现原理主要是使用linux提供的crontab机制,定时查询服务器进程是否存在,如果宕机则执行我们预设的重启脚本. 首先我们要向crontab加入一个新任务 sudo crontab -e #进入编 ...

  2. springboot-admin自定义事件通知

    springboot-admin组建已经提供了很多开箱即用的通知器(例如邮件),但在有些业务场景下我们需要做一些企业内部的通知渠道,这就需要我们来自定义通知器. 实现其实很简单,只需要往spring注 ...

  3. datagrip离线安装驱动jar

    问题描述: datagrip离线安装驱动,在线的安装驱动一般默认安装在当前用户下.DataGrip xxxx 问题解决: 在线在线下载驱动jar,复制jar到内网离线环境 01.外网已经存在的jar提 ...

  4. js 动态生成html 触发事件传参字符转义

    通常,在使用 JS 动态生成 html 的过程中,会嵌入相应的样式.事件等属性元素,而这时经常会出现所谓的 “单.双引号不够用” 的情况,别急,这时可以利用 html 语言中的转义字符来解决.下面就来 ...

  5. 深入理解Linux内存分配

    深入理解Linux内存分配 为了写一个用户层程序,你也许会声明一个全局变量,这个全局变量可能是一个int类型也可能是一个数组,而声明之后你有可能会先初始化它,也有可能放在之后用到它的时候再初始化.除此 ...

  6. 模拟真实点击click,专门对付clickoutside

    var evmousedown = document.createEvent('HTMLEvents'); // evmousedown.clientX = 88 // evmousedown.cli ...

  7. python3 --- locale命名空间让程序更加安全了

    [简介] 由于python-2.x 并没有locale这个层次的命名空间,所以临时变量有可能会泄漏,进而影响到了包涵它的命名空间 [看一下pyhont-2.x是怎么泄漏临时变量的] python Py ...

  8. 【iCore4 双核心板_ARM】例程三十二:UART_IAP_ARM实验——更新升级STM32

    实验现象及操作说明: 1.本例程共有两个代码包,APP和IAP,IAP程序功能实现将APP程序升级至STM32中. 2.直接上电或烧写程序将执行升级的APP应用程序. BIN升级文件产生方法: 1.编 ...

  9. ionic入门教程-ionic路由详解(state、route、resolve)(转)

    http://blog.csdn.net/onil_chen/article/details/51758696?appinstall=0 今天好好的跟大家讲讲ionic的路由配置. 问到的朋友有点多, ...

  10. CUDA加opencv复现导向滤波算法

    CUDA是GPU通用计算的一种,其中现在大热的深度学习底层GPU计算差不多都选择的CUDA,在这我们先简单了解下其中的一些概念,为了好理解,我们先用DX11里的Compute shader来和CUDA ...