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

好好的代码被 \(extra\ test\) 卡常了。。。我就放一个目前最快的版本吧。。。

题意简化:

有 \(n\) 个栈,\(m\) 次操作。

  • 将 \(x\) 压入 \([l,r]\) 的栈中

  • 将 \(l\) 的栈顶弹出

  • 询问 \([l,r]\) 栈顶的和

\(n,m\leq 5\times 10^5\)

虽然最优解是神仙二叉树,我只会主席树的解法。。。

显然 \(1,3\) 操作用一棵线段树就够了,\(2\) 操作需要另外一棵主席树,并且在历史版本上修改。

\(Code\ Below:\)

#include <bits/stdc++.h>
using namespace std;
const int maxn=500000+10;
int n,m,k,a[maxn]; namespace IO{
#define gc() (iS==iT?(iT=(iS=ibuff)+fread(ibuff,1,SIZ,stdin),(iS==iT?EOF:*iS++)):*iS++)
const int SIZ=1<<21|1;
char *iS,*iT,ibuff[SIZ],obuff[SIZ],*oS=obuff,*oT=oS+SIZ-1,fu[110],c;int fr;
inline void out(){
fwrite(obuff,1,oS-obuff,stdout);
oS=obuff;
}
template <class T>
inline void read(T &x){
x=0;T y=1;
for(c=gc();(c>'9'||c<'0')&&c!='-';c=gc());
c=='-'?y=-1:x=(c&15);
for(c=gc();c>='0'&&c<='9';c=gc()) x=x*10+(c&15);
x*=y;
}
template <class T>
inline void print(T x,char text='\n'){
if(x<0) *oS++='-',x*=-1;
if(x==0) *oS++='0';
while(x) fu[++fr]=x%10+'0',x/=10;
while(fr) *oS++=fu[fr--];
*oS++=text;out();
}
} struct President_Tree{
#define rt(x) PT.rt[x]
struct node{
int sum,lazy,ls,rs;
}t[maxn*80];
int rt[maxn],cnt;
inline void pushdown(int x){
if(t[x].lazy){
if(!t[x].ls) t[x].ls=++cnt;
if(!t[x].rs) t[x].rs=++cnt;
t[t[x].ls].sum=t[t[x].rs].sum=t[t[x].ls].lazy=t[t[x].rs].lazy=t[x].lazy;
t[x].lazy=0;
}
}
inline void update(int &x,int y,int L,int R,int C,int l,int r){
x=++cnt;
if(L <= l && r <= R){t[x].sum=t[x].lazy=C;return;}
pushdown(y);t[x].ls=t[y].ls;t[x].rs=t[y].rs;
int mid=(l+r)>>1;
if(L <= mid) update(t[x].ls,t[y].ls,L,R,C,l,mid);
if(R > mid) update(t[x].rs,t[y].rs,L,R,C,mid+1,r);
}
inline int query(int x,int l,int r,int k){
if(l == r) return t[x].sum;
pushdown(x);
int mid=(l+r)>>1;
if(k <= mid) return query(t[x].ls,l,mid,k);
else return query(t[x].rs,mid+1,r,k);
}
}PT; struct Segment_Tree{
#define lson (rt<<1)
#define rson (rt<<1|1)
int sum[maxn<<2],lazy[maxn<<2];
inline void pushup(int rt){sum[rt]=sum[lson]+sum[rson];}
inline void pushdown(int rt,int len){
if(lazy[rt]){
sum[lson]=(len-(len>>1))*lazy[rt];
sum[rson]=(len>>1)*lazy[rt];
lazy[lson]=lazy[rson]=lazy[rt];
lazy[rt]=0;
}
}
inline void update(int L,int R,int C,int l,int r,int rt){
if(L <= l && r <= R){
sum[rt]=(r-l+1)*C;lazy[rt]=C;
return ;
}
pushdown(rt,r-l+1);
int mid=(l+r)>>1;
if(L <= mid) update(L,R,C,l,mid,lson);
if(R > mid) update(L,R,C,mid+1,r,rson);
pushup(rt);
}
inline int query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R) return sum[rt];
pushdown(rt,r-l+1);
int mid=(l+r)>>1,ans=0;
if(L <= mid) ans+=query(L,R,l,mid,lson);
if(R > mid) ans+=query(L,R,mid+1,r,rson);
return ans;
}
}ST; int main()
{
IO::read(n),IO::read(m),IO::read(k);
int op,l,r,x,y,lastans=0;
for(int i=1;i<=n;i++){
rt(i)=rt(i-1);
IO::read(op);
if(op==1){
IO::read(l),IO::read(r);
l=(l+k*lastans)%n+1;
r=(r+k*lastans)%n+1;
if(l>r) swap(l,r);
IO::print(lastans=ST.query(l,r,1,n,1));
}
if(op==2){
IO::read(l);
l=(l+k*lastans)%n+1;
x=PT.query(rt(i),1,n,l);
if(x){
y=PT.query(rt(x-1),1,n,l);
PT.update(rt(i),rt(i),l,l,y,1,n);
ST.update(l,l,a[y],1,n,1);
}
}
if(op==3){
IO::read(l),IO::read(r);
l=(l+k*lastans)%n+1;
r=(r+k*lastans)%n+1;
if(l>r) swap(l,r);
IO::read(x);a[i]=x;
PT.update(rt(i),rt(i),l,r,i,1,n);
ST.update(l,r,x,1,n,1);
}
}
return 0;
}

【UNR #1】火车管理(主席树)的更多相关文章

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

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

  2. UNR #1 火车管理

    很简单 用一个线段树维护 1.答案 2.当前栈顶是什么时候push进来的 然后用一棵以时间为版本的可持久化线段树维护每个操作之后第一个覆盖到他的操作是哪个 就可以了 询问直接在线段树上询问,修改在两棵 ...

  3. 【UNR #1】火车管理

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

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

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

  5. [bzoj3932][CQOI2015][任务查询系统] (主席树)

    Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si ...

  6. POJ 2104&HDU 2665 Kth number(主席树入门+离散化)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 50247   Accepted: 17101 Ca ...

  7. bzoj 3932 [CQOI2015]任务查询系统(主席树)

    Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分. 超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si ...

  8. UOJ 218 火车管理

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

  9. 【BZOJ3932】任务查询系统(主席树)

    [BZOJ3923]任务查询系统(主席树) 题面 Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei ...

随机推荐

  1. 再谈PHP设计模式

    设计模式 单例模式解决的是如何在整个项目中创建唯一对象实例的问题,工厂模式解决的是如何不通过new建立实例对象的方法. 单例模式 $_instance必须声明为静态的私有变量 构造函数和析构函数必须声 ...

  2. Django之如何预防csrf功能的方式 form提交与ajax提交

    1. 什么是csrf认证: 主要是防止别人恶意登录你的账户信息用的: 2. csrf认证在django的实现方式: 分为两种, 一种是from表单提交的方式,另一种是ajax提交实现方式 前端: &l ...

  3. 一个linux 4.9,4.14内核的bbr带宽估计偏低问题

    linux 4.9内核,bbr的带宽估计问题. 一个正常的bbr流量图: 对应的ttl图形: 一个异常的bbr流量图: 可以看出,异常的bbr流量图,出现了一个很低的带宽,且稳定在这个带宽10s左右, ...

  4. Linux-vim文本编辑器

    [Vim文本编辑器] vim的三种模式:一般模式.编辑模式.命令模式. * 一般模式: 当你vim filename 编辑一个文件时,一进入该文件就是一般模式了.在这个模式下,你可以做的操作有,上下移 ...

  5. C语言递归函数讲解

    递归函数是什么? 是函数.................... 你可以把它理解成是for循环与死循环的结合的函数.简单的说:递归函数是有条件终止的死循环函数: 死循环函数这里是指在函数体中调用自身: ...

  6. DJango 基础(7)

    常用查询字段常用类型与模型关系表 知识点: 常用的查询 Field的常用参数 常用的模型字段类型 常用的查询 获取所有记录:rs = User.objects.all()获取第一条数据:rs = Us ...

  7. jstl标准标签库 常用标签

    JSTL(JSP Standard Tag Library)标准标签库: 1, 核心标签(最常用, 最重要的) 表达式控制标签 out 输出常量 value---直接赋值 输出变量 default-- ...

  8. gcc 与 g++的区别

    原文: http://www.cnblogs.com/wb118115/p/5969775.html ------------------------------------------------- ...

  9. 解决win10电脑VB虚拟机无法安装64位系统的方法

    64位电脑在VB虚拟机里却只能安装32位系统怎么办? **原因:CPU虚拟化未开启 只要CPU虚拟化开启即可解决问题. 开启步骤: 1.打开电脑设置 2.进入 更新和安全 界面 3.进入 恢复 界面 ...

  10. 【python深入】装饰器理解及使用

    装饰器,其实就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下额外增加功能,装饰器的返回是一个函数对象. 用一个例子来说明一下什么是函数对象: 从这里可以看到,直接在函数后面加bar(),就 ...