uoj218_火车管理
题意
\(n\)个位置,每个位置一个栈,三种操作,询问区间栈顶的和,区间入栈某个数,单点出栈某个数。
分析
- 用一个线段树来维护栈顶的和,区间(单点)更新和区间询问。
- 用一个主席树来维护每个位置最新一次入栈的时间,即主席树存的是时间,然后取出的时间也能作为主席树的下标来访问对应时间的版本。
- 因此区间入栈的时候区间更新线段树和区间更新主席树。
- 单点出栈时,先查询这个位置栈顶元素的入栈时间,然后再用这个时间的上一个版本的主席树查询栈顶下一个元素的入栈时间,根据入栈时间可以知道入栈的元素,然后由于栈顶已经出栈,所以新的栈顶就是该元素,单点更新线段树和主席树。
代码
#include <bits/stdc++.h>
#define ls i<<1
#define rs i<<1|1
#define mid (l+r)/2
using namespace std;
typedef long long ll;
const int N=8e5+50;
int n,m,ty,o,l1,r1,x[N];
struct ST{
//lz:区间赋值标记 sum:区间和
ll lz[N*4],sum[N*4];
void pushup(int i){
sum[i]=sum[ls]+sum[rs];
}
void pushdown(int i,int l,int r){
if(lz[i]){
lz[ls]=lz[i];
lz[rs]=lz[i];
sum[ls]=(mid-l+1)*lz[i];
sum[rs]=(r-mid)*lz[i];
lz[i]=0;
}
}
void update(int i,int l,int r,int ql,int qr,int v){
if(ql<=l && qr>=r){
lz[i]=v;
sum[i]=1ll*(r-l+1)*v;
return;
}
pushdown(i,l,r);
if(ql<=mid){
update(ls,l,mid,ql,qr,v);
}
if(qr>mid){
update(rs,mid+1,r,ql,qr,v);
}
pushup(i);
}
ll query(int i,int l,int r,int ql,int qr){
if(ql<=l && qr>=r){
return sum[i];
}
pushdown(i,l,r);
ll ans=0;
if(ql<=mid){
ans+=query(ls,l,mid,ql,qr);
}
if(qr>mid){
ans+=query(rs,mid+1,r,ql,qr);
}
return ans;
}
}st;
int tr[N];
struct CT{
int tot=0,tim[N*50],lr[N*50],rr[N*50];
int update(int pre,int l,int r,int ql,int qr,int t){
int rt=++tot;
tim[rt]=t;
lr[rt]=lr[pre];
rr[rt]=rr[pre];
if(ql<=l && qr>=r){
lr[rt]=rr[rt]=(l==r?0:rt);
}else{
if(ql<=mid){
lr[rt]=update(lr[pre],l,mid,ql,qr,t);
}
if(qr>mid){
rr[rt]=update(rr[pre],mid+1,r,ql,qr,t);
}
}
return rt;
}
int query(int i,int l,int r,int v){
if(l==r && l==v){
return tim[i];
}
if(v<=mid){
return query(lr[i],l,mid,v);
}else{
return query(rr[i],mid+1,r,v);
}
}
}ct;
int dec(int l1,int lst){
return (l1+lst*ty)%n+1;
}
int main(){
// freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&m,&ty);
ll lst=0;
for(int t=1;t<=m;t++){
scanf("%d",&o);
tr[t]=tr[t-1];
if(o==1){
scanf("%d%d",&l1,&r1);
l1=dec(l1,lst);
r1=dec(r1,lst);
int l=min(l1,r1);
int r=max(l1,r1);
//直接查询线段树区间和
lst=st.query(1,1,n,l,r);
printf("%lld\n",lst);
}else if(o==2){
scanf("%d",&l1);
int l=dec(l1,lst);
//查询l这个位置最新插入的时间
int tm=ct.query(tr[t],1,n,l);
//查询再前一个插入时间,即将最新插入出栈
int pt=ct.query(tr[tm-1],1,n,l);
//线段树单点修改为上一个版本
st.update(1,1,n,l,l,x[pt]);
//主席树对当前最新版本单点修改l位置的插入时间
tr[t]=ct.update(tr[t],1,n,l,l,pt);
}else if(o==3){
scanf("%d%d%d",&l1,&r1,&x[t]);
l1=dec(l1,lst);
r1=dec(r1,lst);
int l=min(l1,r1);
int r=max(l1,r1);
//线段树区间更新
st.update(1,1,n,l,r,x[t]);
//前面已经有tr[t]=tr[t-1] 无论更不更新都复制一个新版本
//主席树区间更新
tr[t]=ct.update(tr[t],1,n,l,r,t);
}
}
return 0;
}
uoj218_火车管理的更多相关文章
- 【UNR #1】火车管理(主席树)
[UNR #1]火车管理(主席树) 好好的代码被 \(extra\ test\) 卡常了...我就放一个目前最快的版本吧... 题意简化: 有 \(n\) 个栈,\(m\) 次操作. 将 \(x\) ...
- 「UOJ218」火车管理
「UOJ218」火车管理 解题思路:观察发现,在弹出 \(x\) 之前,它前面这个元素都是保持不变的,所以可以用一棵可持久化线段树维护每一个栈顶元素的插入时间,每次找到当前时间\(-1\) 的版本就可 ...
- 【UNR #1】火车管理
题目描述 uoj 旗下有一个火车站,用来管理属于 uoj 的小火车. 火车站一共有 nn 条编号为 1,…,n1,…,n 的,只有一端的用来存放小火车的铁路,由于小火车特殊的构造,每条铁路可以停放无数 ...
- UOJ 218 火车管理
http://uoj.ac/problem/218 思路:建立一个可持久化线段树,代表这个位置的火车是哪辆,然后再弄一个线段树维护答案. 如果询问,直接询问线段树. 如果区间压入,直接在主席树上面压入 ...
- 【UOJ UNR #1】火车管理
来自FallDream的博客,未经允许,请勿转载,谢谢. 题面 考虑用可持久化线段树直接维护每个点在不同时刻,第一辆车的编号. 这样3操作就变成了区间赋值,1操作变成区间和 2操作的话,只需要查询一下 ...
- UOJ#218. 【UNR #1】火车管理 线段树 主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和 ...
- UOJ #218. 【UNR #1】火车管理
Description Solution 实际上添加问题就是一个线段树区间覆盖问题,打标记就好 对于弹栈操作比较难搞,实际上也就是一个历史查询,我们不需要保存栈中的每一个元素,我们通过查找历史状态就可 ...
- [UOJ218]火车管理
建一棵答案线段树存栈顶值,两棵可持久化线段树分别存栈顶值和栈顶元素入栈时间 询问就直接在答案线段树上查,弹栈就用入栈时间在对应版本的可持久化线段树上查询即可,修改就是可持久化线段树的区间覆盖 以前一直 ...
- 【UOJ UNR #1】火车管理 可持久化线段树
用可持久化线段树维护每个站的第一辆车和每个站的前一次更新的位置即可. #include<iostream> #include<cstring> #include<cstd ...
随机推荐
- Python3学习笔记(一): 环境安装
一.下载Python软件包 进入官网https://www.python.org/downloads/,下载符合你当前OS的版本 我用的是Win7 64位系统,在这里下载的是Windows 64位可执 ...
- 「雅礼集训 2017 Day5」远行
题目链接 问题分析 要求树上最远距离,很显然就想到了树的直径.关于树的直径,有下面几个结论: 如果一棵树的直径两个端点为\(a,b\),那么树上一个点\(v\)开始的最长路径是\(v\rightarr ...
- 3.1 JAVA集合框架以及区别
涉及的参考链接:https://www.runoob.com/java/java-collections.html,http://how2j.cn/k/collection/collection-ar ...
- webpack3升级webpack4
cnpm i webpck@4 webpack-cli -D cnpm i webpack-cli -D cnpm update npm WARN deprecated extract-text-we ...
- 有关C#写一个WindowsService的两篇文章
1.http://blog.csdn.net/yysyangyangyangshan/article/details/10515035 上面的这篇文章一共两段,第二段讲的是使用代码来安装发布这个Win ...
- ActiveMQ配置文档
本文介绍一对一.一对多.持久化.非持久化消息配置方式 一.创建项目 导入jar 二.创建MQ.xml <!-- 配置JMS连接工厂 --> <bean id="connec ...
- AC自动机小记
不知不觉这篇博客已经被我咕咕咕了一个月了. 也许我写过AC自动机的博客,但我也不知道我写没写过 前情回顾之\(kmp\) \(kmp\)用来解决一个模式串匹配一个文本串的问题,其思路是设置失配指针,找 ...
- hash模块MD5加密
MD5加密:获取32位加密字符串: 示例(MD5加密'123456')import hashlibhashObject=hashlib.md5(b'123456') #实例化,加密字符串不能直接加密, ...
- zabbix服务器性能监控工具的安装二
上一篇完成了lnmp的安装,本篇则可以继续完成zabbix的安装 目录 1.下载 2.安装 1.下载 下载链接:http://jaist.dl.sourceforge.net/project/zabb ...
- Java学习之==>面向对象编程 Part1
一.面向对象与面向过程 1.面向过程 角度是功能,以方法为最小单位,思考的是具体怎么做. 2.面向对象 角度是抽象,以类为最小单位,思考的是谁来做. 3.示例:“小明去上班” 面向过程 起床,刷牙洗脸 ...