很简单

用一个线段树维护

1.答案

2.当前栈顶是什么时候push进来的

然后用一棵以时间为版本的可持久化线段树维护每个操作之后第一个覆盖到他的操作是哪个

就可以了

询问直接在线段树上询问,修改在两棵树上分别修改即可

调一年

//wls niubi!
#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
int x = ,f = ;char ch = getchar();
for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
for(;isdigit(ch);ch = getchar())x = * x + ch - '';
return x * f;
}
const int maxn = ;
int n,m,ty,rt;
int tot;
int dfn,root[maxn],ls[maxn << ],rs[maxn << ],val[maxn << ],tag[maxn << ],w[maxn];
inline void pushdown(int x,int l,int r)
{
if(l == r || !tag[x])return;
int t = tag[x],mid = (l + r) >> ;tag[x] = ;
if(!ls[x])ls[x] = ++dfn;
if(!rs[x])rs[x] = ++dfn;
tag[ls[x]] = tag[rs[x]] = t;
val[ls[x]] = w[t] * (mid - l + );
val[rs[x]] = w[t] * (r - mid);
}
inline int query(int x,int l,int r,int L,int R)
{
if(!x)return ;
pushdown(x,l,r);
if(L <= l && r <= R)return val[x];
int mid = (l + r) >> ,ans = ;
if(L <= mid)ans += query(ls[x],l,mid,L,R);
if(R > mid)ans += query(rs[x],mid + ,r,L,R);
return ans;/*
if(R <= mid)return query(ls[x],l,mid,L,R);
else if(L > mid)return query(rs[x],mid + 1,r,L,R);
else return query(ls[x],l,mid,L,R) + query(rs[x],mid + 1,r,L,R);*/
}
inline int qid_1(int x,int l,int r,int p)
{
if(tag[x])return tag[x];
if(l == r)return tag[x];
int mid = (l + r) >> ;
if(p <= mid)return qid_1(ls[x],l,mid,p);
else return qid_1(rs[x],mid + ,r,p);
}
inline int qid_2(int x,int l,int r,int p)
{
pushdown(x,l,r);
if(l == r)return tag[x];
int mid = (l + r) >> ;
if(p <= mid)return qid_2(ls[x],l,mid,p);
else return qid_2(rs[x],mid + ,r,p);
}
inline void modify(int &x,int l,int r,int L,int R,int va)
{
if(!x)x = ++dfn;
pushdown(x,l,r);
if(L <= l && r <= R)
{
tag[x] = va;
val[x] = (r - l + ) * w[va];
return;
}
int mid = (l + r) >> ;
if(L <= mid)modify(ls[x],l,mid,L,R,va);
if(R > mid)modify(rs[x],mid + ,r,L,R,va);
val[x] = val[ls[x]] + val[rs[x]];
}
inline void Cpushdown(int x)
{
if(!tag[x])return;
int v = tag[x],tmp;tag[x] = ;
tmp = ls[x],ls[x] = ++dfn;ls[ls[x]] = ls[tmp],rs[ls[x]] = rs[tmp],tag[ls[x]] = tag[tmp],val[ls[x]] = val[tmp];
tmp = rs[x],rs[x] = ++dfn;ls[rs[x]] = ls[tmp],rs[rs[x]] = rs[tmp],tag[rs[x]] = tag[tmp],val[rs[x]] = val[tmp];
tag[ls[x]] = tag[rs[x]] = v;
}
inline void insert(int &x,int l,int r,int L,int R,int va,int flg)
{
if(flg)
{
int p = x;
x = ++dfn;
ls[x] = ls[p],rs[x] = rs[p],tag[x] = tag[p],val[x] = val[p];
}
flg = ;
if(l < r && tag[x])Cpushdown(x),flg = ;
if(L <= l && r <= R){tag[x] = va;return;}
int mid = (l + r) >> ;
if(L <= mid)insert(ls[x],l,mid,L,R,va,flg);
if(R > mid)insert(rs[x],mid + ,r,L,R,va,flg);
}
int main()
{
n=read();m=read();ty=read();
int ans=;
while(m--)
{
int op=read();
if (op==)
{
int l=(read()+ans*ty)%n+,r=(read()+ans*ty)%n+;
if (l>r) swap(l,r);
printf("%d\n",ans=query(rt,,n,l,r));
}
else if (op==)
{
int l=(read()+ans*ty)%n+,id=qid_2(rt,,n,l);
id=qid_1(root[id-],,n,l);
modify(rt,,n,l,l,id);
tot++;root[tot]=root[tot-];
insert(root[tot],,n,l,l,id,);
}
else
{
int l=(read()+ans*ty)%n+,r=(read()+ans*ty)%n+,x=read();
if (l>r) swap(l,r);
tot++;w[tot]=x;root[tot]=root[tot-];
insert(root[tot],,n,l,r,tot,);
modify(rt,,n,l,r,tot);
}
}
}

UNR #1 火车管理的更多相关文章

  1. 【UNR #1】火车管理(主席树)

    [UNR #1]火车管理(主席树) 好好的代码被 \(extra\ test\) 卡常了...我就放一个目前最快的版本吧... 题意简化: 有 \(n\) 个栈,\(m\) 次操作. 将 \(x\) ...

  2. 「UOJ218」火车管理

    「UOJ218」火车管理 解题思路:观察发现,在弹出 \(x\) 之前,它前面这个元素都是保持不变的,所以可以用一棵可持久化线段树维护每一个栈顶元素的插入时间,每次找到当前时间\(-1\) 的版本就可 ...

  3. 【UNR #1】火车管理

    题目描述 uoj 旗下有一个火车站,用来管理属于 uoj 的小火车. 火车站一共有 nn 条编号为 1,…,n1,…,n 的,只有一端的用来存放小火车的铁路,由于小火车特殊的构造,每条铁路可以停放无数 ...

  4. 【UOJ UNR #1】火车管理

    来自FallDream的博客,未经允许,请勿转载,谢谢. 题面 考虑用可持久化线段树直接维护每个点在不同时刻,第一辆车的编号. 这样3操作就变成了区间赋值,1操作变成区间和 2操作的话,只需要查询一下 ...

  5. UOJ#218. 【UNR #1】火车管理 线段树 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和 ...

  6. UOJ #218. 【UNR #1】火车管理

    Description Solution 实际上添加问题就是一个线段树区间覆盖问题,打标记就好 对于弹栈操作比较难搞,实际上也就是一个历史查询,我们不需要保存栈中的每一个元素,我们通过查找历史状态就可 ...

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

    用可持久化线段树维护每个站的第一辆车和每个站的前一次更新的位置即可. #include<iostream> #include<cstring> #include<cstd ...

  8. Uoj #218. 【UNR #1】火车管理 可持久化线段树+思维

    Code: #include<bits/stdc++.h> #define maxn 500005 using namespace std; int n,Q,ty,lastans=0; i ...

  9. UOJ 218 火车管理

    http://uoj.ac/problem/218 思路:建立一个可持久化线段树,代表这个位置的火车是哪辆,然后再弄一个线段树维护答案. 如果询问,直接询问线段树. 如果区间压入,直接在主席树上面压入 ...

随机推荐

  1. Snubber电路

    http://www.elecfans.com/yuanqijian/dianrongqi/20170601520736.html https://wenku.baidu.com/view/166f1 ...

  2. vim 穿越时空

    1. 回到以前的文件状态 :earlier 3m   回到文件3分钟之前的状态 2. 回到以后的文件状态 :later 3m      回到文件3分钟之后的状态 3. 时间单位 s 秒 m 分钟 d ...

  3. PX4学习之-uORB简单体验

    一.前言 最近项目使用到 CPU2 与 CPU0 之间的通信, 使用定时器传递消息到 CPU0 后, CPU0 需要将消息分发到不同的应用程序里面. PX4 里面使用的是 uORB 多线程/进程通信机 ...

  4. 初识Dubbo 系列之6-Dubbo 配置

    配置 Xml配置 配置项说明 具体配置项,请參见:配置參考手冊 (+) API使用说明 假设不想使用Spring配置.而希望通过API的方式进行调用,请參见:API配置 (+) 配置使用说明 想知道怎 ...

  5. 现在有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1,y1)。每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转。问最少需要移动几步。

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...

  6. 在一个JS文件中引用另一个JS文件

    方法一,在调用文件的顶部加入下例代码: document.write(”<script language=javascript src=’/js/import.js’></scrip ...

  7. iOS项目 -- 模仿花椒直播做的第三层设计完整版

    由于是获取第三方的数据,开发的时候,把数据结构分为:闭环数据,和开环数据. 开环数据是网络的第三方数据,自己不能控制的了. 闭环数据是自己的数据,可以进行各式各样的设计. 这是闭环数据的数据库关键字设 ...

  8. BZOJ 1597: [Usaco2008 Mar]土地购买 斜率优化

    1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MB Description 农夫John准备扩大他的农场,他正在考虑N ...

  9. 九度OJ 1171:C翻转 (矩阵计算)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4649 解决:1530 题目描述: 首先输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作 ...

  10. win7怎么设置打印机共享

    一.设置好家庭组,让客户机加入家庭组 二.对服务机的打印机进行共享设置,如果保存不成功请在计算机服务那里打开防火墙 三.1.开启guest用户,具体操作:我的电脑右击---管理---本地用户和组--开 ...