【UOJ #218. 【UNR #1】】火车管理 可持久化线段树

题目:
uoj 旗下有一个火车站,用来管理属于 uoj 的小火车。

火车站一共有 n
n
条编号为 1,…,n
1,…,n
的,只有一端的用来存放小火车的铁路,由于小火车特殊的构造,每条铁路可以停放无数辆小火车。每条铁路是相互独立的。

铁路是一个栈结构,后停放的小火车可以先出来。

每辆小火车有一个吨位 t
t

由于 NOI2016 即将到来,想要跟小火车正面作战的人多了起来,火车站管理员九条可怜每天需要处理很多事件。

事件可以概括成一下三种:
•1 l r 有人想跟铁路编号在 [l,r]
[l,r]
的每条铁路的第一辆可以开出来的小火车正面战斗,你需要统计这些小火车的吨位之和,没有火车的铁路不计入答案。
•2 l 编号为 l
l
的铁路开走一辆火车,如果这条铁路没有小火车则不开出。
•3 l r x 铁路编号在 [l,r]
[l,r]
的每条铁路都新停放一辆吨位为 x
x
的火车。

现在管理员九条可怜要去南海前线了,你需要替他管理火车站。

由于火车站很忙,所以你需要实时反馈信息,我们会用一些手段要求你强制在线,具体请看输入格式。

输入格式

输入第一行三个非负整数 n,m,ty
n,m,ty
表示铁路的数量和操作次数还有是否强制在线。

接下来 m
m
行,每行四个数或者三个数或者两个数表示一次操作。

为了实时反馈信息,你需要解密 l,r
l,r
,设读入的是 l1,r1
l1,r1
,则实际的值如下:

l2r2lr====(l1+lastans⋅ty)modn+1(r1+lastans⋅ty)modn+1min(l2,r2)max(l2,r2)
l2=(l1+lastans⋅ty)modn+1r2=(r1+lastans⋅ty)modn+1l=min(l2,r2)r=max(l2,r2)

lastans
lastans
表示上一次询问的答案,如果之前没有询问则为 0
0

当你进行的是第二类操作时,只需要令 l=(l1+lastans⋅ty)modn+1
l=(l1+lastans⋅ty)modn+1
即可。

输入数据保证 1≤l1,r1≤n
1≤l1,r1≤n

注意,我们并没有加密吨位和操作类型

输出格式

对于每个询问输出一行,一个非负整数表示答案。

样例一

input
10 10 0
3 1 5 3
1 1 6
3 1 7 1
1 1 9
1 1 6
3 1 5 2
1 3 6
1 3 9
3 1 7 6
2 1

output
15
7
6
7
8

http://uoj.ac/problem/218
题解:

我们可以针对时间建立一颗可持久化线段树,维护每个铁路每个时间的栈顶的吨位和栈顶火车的入栈时间。
我们再维护一颗线段树用来统计答案。
于是操作就只有三种了:
区间询问:直接在答案线段树里询问即可。
区间压数:在可持久化线段树上进行区间覆盖,然后在答案线段树上修改一下。
单点弹数:由于我们记录了入栈时间,查询到入站时间t后,我们可以查询t时刻前的树,查出当前点入栈之前的栈顶的信息,然后在答案线段树上和可持久化线段树上修改。

代码

#include<iostream>
#include<stdio.h>
#include<string.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值