UOJ#218. 【UNR #1】火车管理 线段树 主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html
题解
如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖、区间求和的线段树上完成这个问题。
于是本题的重点转到了如何求新的栈顶。
考虑用一个主席树维护一下每一个时刻每一个位置的栈顶元素的进栈时间,那么新的栈顶就是 当前位置栈顶的进栈时间-1 这时候的栈顶元素,然后这个东西也可以用我们维护的进栈时间来得到,所以我们只需要弄一个支持区间覆盖单点查询历史版本的主席树;这里区间覆盖有一个小技巧:假设节点 x 所代表的区间都被覆盖了,那么修改完 val[x] 之后令 ls[x] = rs[x] = x 即可。
代码
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=500005;
int n,m,k;
int lastans=0;
int hisv[N];
namespace seg{
const int S=N<<2;
int sum[S],add[S],len[S];
void build(int rt,int L,int R){
len[rt]=R-L+1,sum[rt]=add[rt]=0;
if (L==R)
return;
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
build(ls,L,mid);
build(rs,mid+1,R);
}
void pushdown(int rt){
int ls=rt<<1,rs=ls|1;
if (add[rt]){
add[ls]=add[rs]=add[rt];
sum[ls]=add[rt]*len[ls];
sum[rs]=add[rt]*len[rs];
add[rt]=0;
}
}
void update(int rt,int L,int R,int xL,int xR,int v){
if (R<xL||L>xR)
return;
if (xL<=L&&R<=xR){
sum[rt]=v*len[rt];
add[rt]=v;
return;
}
pushdown(rt);
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
update(ls,L,mid,xL,xR,v);
update(rs,mid+1,R,xL,xR,v);
sum[rt]=sum[ls]+sum[rs];
}
int Query(int rt,int L,int R,int xL,int xR){
if (R<xL||L>xR)
return 0;
if (xL<=L&&R<=xR)
return sum[rt];
pushdown(rt);
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
return Query(ls,L,mid,xL,xR)+Query(rs,mid+1,R,xL,xR);
}
}
namespace pt{
const int S=N*100;
int val[S],ls[S],rs[S],root[N],cnt;
void init(){
root[0]=cnt=ls[1]=rs[1]=1;
val[1]=0;
}
void update(int prt,int &rt,int L,int R,int xL,int xR,int v){
if (R<xL||L>xR)
return;
if (rt==prt)
rt=++cnt,val[rt]=val[prt],ls[rt]=ls[prt],rs[rt]=rs[prt];
if (xL<=L&&R<=xR){
val[rt]=v;
ls[rt]=rs[rt]=rt;
return;
}
int mid=(L+R)>>1;
update(ls[prt],ls[rt],L,mid,xL,xR,v);
update(rs[prt],rs[rt],mid+1,R,xL,xR,v);
}
int Query(int rt,int L,int R,int x){
if (L==R)
return val[rt];
int mid=(L+R)>>1;
if (x<=mid)
return Query(ls[rt],L,mid,x);
else
return Query(rs[rt],mid+1,R,x);
}
}
using pt::root;
int main(){
n=read(),m=read(),k=read();
seg::build(1,1,n);
pt::init();
hisv[0]=0;
for (int T=1;T<=m;T++){
root[T]=root[T-1];
int type=read(),L=(read()+lastans*k)%n+1,R,x;
if (type==1){
R=(read()+lastans*k)%n+1;
if (L>R)
swap(L,R);
printf("%d\n",lastans=seg::Query(1,1,n,L,R));
}
else if (type==2){
int t1=pt::Query(root[T-1],1,n,L);
t1=pt::Query(root[max(t1-1,0)],1,n,L);
seg::update(1,1,n,L,L,hisv[t1]);
pt::update(root[T-1],root[T],1,n,L,L,t1);
}
else if (type==3){
R=(read()+lastans*k)%n+1,x=read();
if (L>R)
swap(L,R);
hisv[T]=x;
seg::update(1,1,n,L,R,x);
pt::update(root[T-1],root[T],1,n,L,R,T);
}
}
return 0;
}
UOJ#218. 【UNR #1】火车管理 线段树 主席树的更多相关文章
- 线段树简单入门 (含普通线段树, zkw线段树, 主席树)
线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...
- 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))
函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...
- 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题
“队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄> 线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...
- Luogu5289 十二省联考2019字符串问题(后缀数组+拓扑排序+线段树/主席树/KDTree)
先考虑80分做法,即满足A串长度均不小于B串,容易发现每个B串对应的所有A串在后缀数组上都是一段连续区间,线段树优化连边然后判环求最长链即可.场上就写了这个. 100分也没有什么本质区别,没有A串长度 ...
- Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)
Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...
- 小结:线段树 & 主席树 & 树状数组
概要: 就是用来维护区间信息,然后各种秀智商游戏. 技巧及注意: 一定要注意标记的下放的顺序及影响!考虑是否有叠加或相互影响的可能! 和平衡树相同,在操作每一个节点时,必须保证祖先的tag已经完全下放 ...
- BZOJ5011 [JXOI2017]颜色 【线段树 + 主席树】
题目链接 BZOJ5011 题解 一定只有我这种智障会用这么奇怪的方法做这道题.. 由题我们知道最后剩余的一定是一个区间,而且区间内的颜色不存在于区间外 所以我们的目的就是为了找到这样的区间的数量 区 ...
- 洛谷P3834 可持久化线段树(主席树)模板
题目:https://www.luogu.org/problemnew/show/P3834 无法忍受了,我要写主席树! 解决区间第 k 大查询问题,可以用主席树,像前缀和一样建立 n 棵前缀区间的权 ...
- [学习笔记] 可持久化线段树&主席树
众所周知,线段树是一个非常好用也好写的数据结构, 因此,我们今天的前置技能:线段树. 然而,可持久化到底是什么东西? 别急,我们一步一步来... step 1 首先,一道简化的模型: 给定一个长度为\ ...
随机推荐
- DRF之频率限制、分页、解析器和渲染器
一.频率限制 1.频率限制是做什么的 开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用. 2.频率组件原理 DRF中的频率控制基本原理是基于访问次数和时间的,当然我们可以通 ...
- B. Vova and Trophies 字符串预处理+思维+贪心
题意:给出一个字符串 只有G和S 可以交换任意两个位置的字符一次 问 最长的G的长度是多少 思路:预处理字符串 把相同的G粘成一个G 记一下数量 字符串变为 GSSGSGGSGSSG 相邻有一个S ...
- html5 基础入门
html5 基础入门 前言介绍 HTML5草案的前身名为 Web Applications 1.0,于2004年被WHATWG提出,于2007年被W3C接纳,并成立了新的 HTML工作团队. 如果从狭 ...
- C/C++ const
一 含义 const修饰的变量在C和C++中的含义是什么?一样吗? 在C中用const修饰的变量仅仅表示这个符合表示的变量不能被赋值,是只读的,那么它与常量有啥区别呢?区别就是一个是常量,一个是变量. ...
- 如何将JPG格式的图片转换成PNG格式
study from : https://jingyan.baidu.com/article/6079ad0e63a4fc28ff86db37.html
- I/O模型
目录: IO模型 阻塞IO 非阻塞IO IO多路复用 异步IO 总结: 1.阻塞IO模型 多线程 多进程 线程池 进程池 全是阻塞IO 2.非阻塞IO 协程是一种非阻塞IO 1.setblocking ...
- 基于Rabbit实现的RPC
最近在学习项目中的通用技术,其中一个是在项目中会经常使用的基于RabbitMQ实现的RPC.这里一共有三个点要学习,分别是:RPC是什么?RabbitMQ是什么?如何使用RabbitMQ实现RPC.奔 ...
- 第一节:WebApi的纯原生态的RestFul风格接口和路由规则介绍
一. 原生态接口 1. 从默认路由开始分析 在WebApiConfig.cs类中的Register方法中,我们可以看到默认路由如下: 分析:请求地址在 controller 前面需要加上 api/,c ...
- [Everyday Mathematics]20150305
设 $f\in C^2[0,1]$, $$\bex f(0)=-1,\quad f'(1)=3,\quad \int_0^1 xf''(x)\rd x=1. \eex$$ 试求 $f(1)$. 解答: ...
- Linux 一块网卡配置多个IP的方法
1:ifconfig eth0:0 192.168.211.200/24 up 2:ip addr add 192.168.211.201/24 dev eth0 labe eth0:1 man ip ...