[UOJ218]火车管理
建一棵答案线段树存栈顶值,两棵可持久化线段树分别存栈顶值和栈顶元素入栈时间
询问就直接在答案线段树上查,弹栈就用入栈时间在对应版本的可持久化线段树上查询即可,修改就是可持久化线段树的区间覆盖
以前一直没写过可持久化线段树的区间覆盖,这里记一下
这题只用单点查询,我们在修改时把对应的区间打上标记并将其儿子设为空,那么单点查询时答案就是访问到的最深的存在的节点
维护区间和也是可以的,直接pushdown,只不过只用对存在的儿子pushdown,在pushup时不存在的儿子的值就是当前节点的标记了
#include<stdio.h>
#include<algorithm>
using namespace std;
char c[20000010];
int ns;
#define NUM(x) ('0'<=x&&x<='9')
int rd(){
while(!NUM(c[ns]))ns++;
int x=0;
while(NUM(c[ns]))x=x*10+c[ns++]-'0';
return x;
}
int n;
struct pseg{
struct seg{
int l,r,v;
}t[40000010];
int rt[5000010],M;
void modify(int pr,int&nr,int L,int R,int v,int l,int r){
t[nr=++M]=t[pr];
if(L<=l&&r<=R){
t[nr].v=v;
t[nr].l=t[nr].r=0;
return;
}
int mid=(l+r)>>1;
if(L<=mid)modify(t[pr].l,t[nr].l,L,R,v,l,mid);
if(mid<R)modify(t[pr].r,t[nr].r,L,R,v,mid+1,r);
}
int query(int p,int l,int r,int x){
if(x==0)return-1;
int mid=(l+r)>>1,res;
if(p<=mid)
res=query(p,l,mid,t[x].l);
else
res=query(p,mid+1,r,t[x].r);
return~res?res:t[x].v;
}
void modify(int t,int l,int r,int v){
modify(rt[t],rt[t],l,r,v,1,n);
}
int query(int t,int p){
return query(p,1,n,rt[t]);
}
}top,in;
int s[2000010],t[2000010];
void gao(int x,int len,int v){
t[x]=v;
s[x]=len*v;
}
void pushdown(int x,int ln,int rn){
if(t[x]){
gao(x<<1,ln,t[x]);
gao(x<<1|1,rn,t[x]);
t[x]=0;
}
}
void pushup(int x){s[x]=s[x<<1]+s[x<<1|1];}
void modify(int L,int R,int v,int l,int r,int x){
if(L<=l&&r<=R)return gao(x,r-l+1,v);
int mid=(l+r)>>1;
pushdown(x,mid-l+1,r-mid);
if(L<=mid)modify(L,R,v,l,mid,x<<1);
if(mid<R)modify(L,R,v,mid+1,r,x<<1|1);
pushup(x);
}
int query(int L,int R,int l,int r,int x){
if(L<=l&&r<=R)return s[x];
int mid=(l+r)>>1,s=0;
pushdown(x,mid-l+1,r-mid);
if(L<=mid)s+=query(L,R,l,mid,x<<1);
if(mid<R)s+=query(L,R,mid+1,r,x<<1|1);
return s;
}
int main(){
fread(c,1,20000010,stdin);
in.t[0].v=-1;
top.t[0].v=-1;
int m,on,las,op,i,l,r,x,v;
n=rd();
m=rd();
on=rd();
las=0;
for(i=1;i<=m;i++){
top.rt[i]=top.rt[i-1];
in.rt[i]=in.rt[i-1];
op=rd();
if(op==1){
l=(rd()+on*las)%n+1;
r=(rd()+on*las)%n+1;
if(l>r)swap(l,r);
las=query(l,r,1,n,1);
printf("%d\n",las);
}
if(op==2){
l=(rd()+on*las)%n+1;
x=in.query(i,l);
if(x>0){
v=in.query(x-1,l);
if(v==-1)v=0;
in.modify(i,l,l,v);
v=top.query(x-1,l);
if(v==-1)v=0;
modify(l,l,v,1,n,1);
top.modify(i,l,l,v);
}
}
if(op==3){
l=(rd()+on*las)%n+1;
r=(rd()+on*las)%n+1;
x=rd();
if(l>r)swap(l,r);
modify(l,r,x,1,n,1);
top.modify(i,l,r,x);
in.modify(i,l,r,i);
}
}
}
[UOJ218]火车管理的更多相关文章
- 「UOJ218」火车管理
「UOJ218」火车管理 解题思路:观察发现,在弹出 \(x\) 之前,它前面这个元素都是保持不变的,所以可以用一棵可持久化线段树维护每一个栈顶元素的插入时间,每次找到当前时间\(-1\) 的版本就可 ...
- 【UNR #1】火车管理(主席树)
[UNR #1]火车管理(主席树) 好好的代码被 \(extra\ test\) 卡常了...我就放一个目前最快的版本吧... 题意简化: 有 \(n\) 个栈,\(m\) 次操作. 将 \(x\) ...
- 【UNR #1】火车管理
题目描述 uoj 旗下有一个火车站,用来管理属于 uoj 的小火车. 火车站一共有 nn 条编号为 1,…,n1,…,n 的,只有一端的用来存放小火车的铁路,由于小火车特殊的构造,每条铁路可以停放无数 ...
- UOJ 218 火车管理
http://uoj.ac/problem/218 思路:建立一个可持久化线段树,代表这个位置的火车是哪辆,然后再弄一个线段树维护答案. 如果询问,直接询问线段树. 如果区间压入,直接在主席树上面压入 ...
- UOJ#218. 【UNR #1】火车管理 线段树 主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和 ...
- 【UOJ UNR #1】火车管理
来自FallDream的博客,未经允许,请勿转载,谢谢. 题面 考虑用可持久化线段树直接维护每个点在不同时刻,第一辆车的编号. 这样3操作就变成了区间赋值,1操作变成区间和 2操作的话,只需要查询一下 ...
- UOJ #218. 【UNR #1】火车管理
Description Solution 实际上添加问题就是一个线段树区间覆盖问题,打标记就好 对于弹栈操作比较难搞,实际上也就是一个历史查询,我们不需要保存栈中的每一个元素,我们通过查找历史状态就可 ...
- 【UOJ UNR #1】火车管理 可持久化线段树
用可持久化线段树维护每个站的第一辆车和每个站的前一次更新的位置即可. #include<iostream> #include<cstring> #include<cstd ...
- UNR #1 火车管理
很简单 用一个线段树维护 1.答案 2.当前栈顶是什么时候push进来的 然后用一棵以时间为版本的可持久化线段树维护每个操作之后第一个覆盖到他的操作是哪个 就可以了 询问直接在线段树上询问,修改在两棵 ...
随机推荐
- Plant (矩阵快速幂)
题目链接:http://codeforces.com/problemset/problem/185/A 题目: Dwarfs have planted a very interesting plant ...
- js基础知识点收集
js基础知识点收集 js常用基本类型 function show(x) { console.log(typeof(x)); // undefined console.log(typeof(10)); ...
- js_读【javascript面向对象编程指南】笔记
写在前面: 工欲善其事,必先利其器.编程的器,是前人总结的经验,常言道站在巨人的肩膀上开发,往往比自己另辟蹊径容易的多.经验藏于书,故有书中自有颜如玉,书中自有黄金屋,我也一度认为读书要花费很多时间, ...
- Eureka服务续约(Renew)源码分析
主要对Eureka的Renew(服务续约),从服务提供者发起续约请求开始分析,通过阅读源码和画时序图的方式,展示Eureka服务续约的整个生命周期.服务续约主要是把服务续约的信息更新到自身的Eurek ...
- Java常用开发思想与知识点小记(一)
1. 子类在覆盖父类的方法时,不能抛出比父类更多的异常(儿子不能比父亲干更多的坏事),所以只能捕捉异常,通常在web层捕获异常,给用户一个友好提示. 2.Java内存模型与并发编程三个特性 htt ...
- selenium 点击浏览器按钮
利用以下的方法,selenium 也可以模拟点击各种浏览器按钮:browser.back()点击“返回”按钮.browser.forward()点击“前进”按钮.browser.refresh()点击 ...
- linux命令面试题
文件管理命令 (1)Linux的文件系统目录配置要遵循FHS规范,规范定义的两级目录规范如下: /home 每个账号在该目录下都有一个文件夹,进行数据的管理 /usr 有 ...
- windows7配置python和django的开发环境
直接上图,这是我在我的电脑配置windows7python和django开发环境的所有用到的软件 要求不高,只需要这几个软件的版本相一致就行, 需要注意的是软件安装时需要统一是32位或者64位的软件, ...
- JVM字节码执行引擎和动态绑定原理
1.执行引擎 所有Java虚拟机的执行引擎都是一致的: 输入的是字节码文件,处理过程就是解析过程,最后输出执行结果. 在整个过程不同的数据在不同的结构中进行处理. 2.栈帧 jvm进行方法调用和方法执 ...
- BZOJ 1010 玩具装箱toy(斜率优化DP)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题目大意:P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他 ...