uoj218_火车管理】的更多相关文章

题意 \(n\)个位置,每个位置一个栈,三种操作,询问区间栈顶的和,区间入栈某个数,单点出栈某个数. 分析 用一个线段树来维护栈顶的和,区间(单点)更新和区间询问. 用一个主席树来维护每个位置最新一次入栈的时间,即主席树存的是时间,然后取出的时间也能作为主席树的下标来访问对应时间的版本. 因此区间入栈的时候区间更新线段树和区间更新主席树. 单点出栈时,先查询这个位置栈顶元素的入栈时间,然后再用这个时间的上一个版本的主席树查询栈顶下一个元素的入栈时间,根据入栈时间可以知道入栈的元素,然后由于栈顶已…
[UNR #1]火车管理(主席树) 好好的代码被 \(extra\ test\) 卡常了...我就放一个目前最快的版本吧... 题意简化: 有 \(n\) 个栈,\(m\) 次操作. 将 \(x\) 压入 \([l,r]\) 的栈中 将 \(l\) 的栈顶弹出 询问 \([l,r]\) 栈顶的和 \(n,m\leq 5\times 10^5\) 虽然最优解是神仙二叉树,我只会主席树的解法... 显然 \(1,3\) 操作用一棵线段树就够了,\(2\) 操作需要另外一棵主席树,并且在历史版本上修改…
「UOJ218」火车管理 解题思路:观察发现,在弹出 \(x\) 之前,它前面这个元素都是保持不变的,所以可以用一棵可持久化线段树维护每一个栈顶元素的插入时间,每次找到当前时间\(-1\) 的版本就可以查到栈顶,另外用一棵线段树维护区间答案即可,复杂度 \(O(m\log n)\) /*program by mangoyang*/ #include <bits/stdc++.h> #define inf (0x7f7f7f7f) #define Max(a, b) ((a) > (b)…
题目描述 uoj 旗下有一个火车站,用来管理属于 uoj 的小火车. 火车站一共有 nn 条编号为 1,…,n1,…,n 的,只有一端的用来存放小火车的铁路,由于小火车特殊的构造,每条铁路可以停放无数辆小火车.每条铁路是相互独立的. 铁路是一个栈结构,后停放的小火车可以先出来. 每辆小火车有一个吨位 tt. 由于 NOI2016 即将到来,想要跟小火车正面作战的人多了起来,火车站管理员九条可怜每天需要处理很多事件. 事件可以概括成一下三种: 1 l r 有人想跟铁路编号在 [l,r][l,r] …
http://uoj.ac/problem/218 思路:建立一个可持久化线段树,代表这个位置的火车是哪辆,然后再弄一个线段树维护答案. 如果询问,直接询问线段树. 如果区间压入,直接在主席树上面压入,然后更新线段树答案 如果弹出,那么直接找主席树当前位之前的火车是那辆,然后修改线段树答案,再修改当前主席树答案. 改题的时候蜜汁错误.. #include<cstdio> #include<cmath> #include<cstring> #include<iost…
来自FallDream的博客,未经允许,请勿转载,谢谢. 题面 考虑用可持久化线段树直接维护每个点在不同时刻,第一辆车的编号. 这样3操作就变成了区间赋值,1操作变成区间和 2操作的话,只需要查询一下现在这辆车的编号,再到历史版本去查一下上一辆车的编号就行了. #include<iostream> #include<cstdio> #define MN 500000 using namespace std; inline int read() { ,f=;char ch=getch…
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和的线段树上完成这个问题. 于是本题的重点转到了如何求新的栈顶. 考虑用一个主席树维护一下每一个时刻每一个位置的栈顶元素的进栈时间,那么新的栈顶就是 当前位置栈顶的进栈时间-1 这时候的栈顶元素,然后这个东西也可以用我们维护的进栈时间来得到,所以我们只需要弄一个支持区间覆盖单点查询历史版本的主席树:这…
Description Solution 实际上添加问题就是一个线段树区间覆盖问题,打标记就好 对于弹栈操作比较难搞,实际上也就是一个历史查询,我们不需要保存栈中的每一个元素,我们通过查找历史状态就可以了 这样用主席树维护复杂度是 \(O(n*logn)\) 的 具体是这样的: 假设我们要弹出位置 \(x\) 的栈顶元素,那么在线段树中维护一个值 \(t\),表示最近的一次修改是 \(t\) 时刻 那么上上次修改就可以通过查询 \(t-1\) 时刻的 \(t\) 找出,相当于保存了一个前驱 用主…
建一棵答案线段树存栈顶值,两棵可持久化线段树分别存栈顶值和栈顶元素入栈时间 询问就直接在答案线段树上查,弹栈就用入栈时间在对应版本的可持久化线段树上查询即可,修改就是可持久化线段树的区间覆盖 以前一直没写过可持久化线段树的区间覆盖,这里记一下 这题只用单点查询,我们在修改时把对应的区间打上标记并将其儿子设为空,那么单点查询时答案就是访问到的最深的存在的节点 维护区间和也是可以的,直接pushdown,只不过只用对存在的儿子pushdown,在pushup时不存在的儿子的值就是当前节点的标记了 #…
用可持久化线段树维护每个站的第一辆车和每个站的前一次更新的位置即可. #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<algorithm> #define maxn 500005 using namespace std; inline int read() { ,f=;char ch=get…