浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html

浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html

题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1500

究极无敌大模板题,记得要写垃圾回收。

时间复杂度:\(O((n+m)logn)\)

空间复杂度:\(O(n)\)

\(splay\)代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn=5e5+5,inf=1e9; char s[20];
int a[maxn];
int n,m,pos,tot; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct Splay {
int root;
int dust[maxn],top;
int val[maxn],sum[maxn];
bool rev[maxn],cov[maxn];
int mx[maxn],lmx[maxn],rmx[maxn];
int siz[maxn],fa[maxn],son[maxn][2]; void clear(int u) {
rev[u]=cov[u]=0;
son[u][0]=son[u][1]=0;
} void update(int u) {
int ls=son[u][0],rs=son[u][1];
siz[u]=siz[ls]+1+siz[rs];
sum[u]=sum[ls]+val[u]+sum[rs];
lmx[u]=max(lmx[ls],sum[ls]+val[u]+lmx[rs]);
rmx[u]=max(rmx[rs],sum[rs]+val[u]+rmx[ls]);
mx[u]=max(max(mx[ls],mx[rs]),rmx[ls]+val[u]+lmx[rs]);
} int build(int l,int r,int lst) {
if(r<l)return 0;
if(l==r) {
int id=dust[top--];
siz[id]=1,fa[id]=lst;
lmx[id]=rmx[id]=max(0,a[l]);
val[id]=sum[id]=mx[id]=a[l];
return id;
}
int mid=(l+r)>>1,id=dust[top--];
val[id]=a[mid],fa[id]=lst;
son[id][0]=build(l,mid-1,id);
son[id][1]=build(mid+1,r,id);
update(id);return id;
} void prepare() {
mx[0]=-inf;
for(int i=1;i<=500002;i++)
dust[++top]=i;
root=build(1,n+2,0);
} void make_cov_tag(int u,int v) {
if(!u)return;
cov[u]=1,val[u]=v,sum[u]=siz[u]*v;
if(v>0)lmx[u]=rmx[u]=mx[u]=siz[u]*v;
else lmx[u]=rmx[u]=0,mx[u]=v;
} void make_rev_tag(int u) {
if(!u)return;
swap(lmx[u],rmx[u]);
rev[u]^=1,swap(son[u][0],son[u][1]);
} void push_down(int u) {
if(cov[u]) {
make_cov_tag(son[u][0],val[u]);
make_cov_tag(son[u][1],val[u]);
cov[u]=0;
}
if(rev[u]) {
make_rev_tag(son[u][0]);
make_rev_tag(son[u][1]);
rev[u]=0;
}
} int find(int u,int rk) {
push_down(u);
if(siz[son[u][0]]+1==rk)return u;
if(siz[son[u][0]]>=rk)return find(son[u][0],rk);
return find(son[u][1],rk-siz[son[u][0]]-1);
} int t(int u) {return son[fa[u]][1]==u;} void rotate(int u) {
int ret=t(u),f=fa[u],s=son[u][ret^1];
son[f][ret]=s;if(s)fa[s]=f;son[u][ret^1]=f;
fa[u]=fa[f];if(fa[f])son[fa[f]][t(f)]=u;
fa[f]=u;update(f),update(u);
} void splay(int goal,int u) {
int tmp=fa[goal];
while(fa[u]!=tmp) {
if(fa[fa[u]]!=tmp) {
if(t(fa[u])==t(u))rotate(fa[u]);
else rotate(u);
}
rotate(u);
}
if(!tmp)root=u;
} void recycle(int u) {
if(!u)return;
dust[++top]=u;
recycle(son[u][0]);
recycle(son[u][1]);
clear(u);
} void ins(int pos) {
for(int i=1;i<=tot;i++)a[i]=read();
int u1=find(root,pos),u2=find(root,pos+1);
splay(root,u1),splay(son[u1][1],u2);
son[u2][0]=build(1,tot,u2);
update(u2),update(u1);
} void del(int l,int r) {
int u1=find(root,l-1),u2=find(root,r+1);
splay(root,u1),splay(son[u1][1],u2);
int tmp=son[u2][0];
son[u2][0]=fa[tmp]=0;
recycle(tmp);
update(u2),update(u1);
} void cover(int l,int r,int v) {
int u1=find(root,l-1),u2=find(root,r+1);
splay(root,u1),splay(son[u1][1],u2);
make_cov_tag(son[u2][0],v);
update(u2),update(u1);
} void rever(int l,int r) {
int u1=find(root,l-1),u2=find(root,r+1);
splay(root,u1),splay(son[u1][1],u2);
make_rev_tag(son[u2][0]);
update(u2),update(u1);
} int query(int l,int r) {
int u1=find(root,l-1),u2=find(root,r+1);
splay(root,u1),splay(son[u1][1],u2);
return sum[son[u2][0]];
}
}T; int main() {
n=read(),m=read();
for(int i=2;i<=n+1;i++)
a[i]=read();
a[1]=a[n+2]=-inf,T.prepare();
for(int i=1;i<=m;i++) {
scanf("%s",s+1);
if(s[1]!='M'||s[4]!='-')
pos=read()+1,tot=read();
if(s[1]=='I')T.ins(pos);
if(s[1]=='D')T.del(pos,pos+tot-1);
if(s[1]=='M'&&s[4]=='E') {
int c=read();
T.cover(pos,pos+tot-1,c);
}
if(s[1]=='R')T.rever(pos,pos+tot-1);
if(s[1]=='G')printf("%d\n",T.query(pos,pos+tot-1));
if(s[1]=='M'&&s[4]=='-')printf("%d\n",T.mx[T.root]);
}
return 0;
}

\(fhq\)_\(treap\)版代码如下:

#include <ctime>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii; const int maxn=5e5+5,inf=1e9; char s[20];
int a[maxn];
int n,m,pos,tot; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct fhq_treap {
int root,top;
int dust[maxn];
bool cov[maxn],rev[maxn];
int fix[maxn],son[maxn][2];
int mx[maxn],lmx[maxn],rmx[maxn];
int val[maxn],sum[maxn],siz[maxn]; void update(int u) {
int ls=son[u][0],rs=son[u][1];
siz[u]=siz[ls]+1+siz[rs];
sum[u]=sum[ls]+val[u]+sum[rs];
lmx[u]=max(lmx[ls],sum[ls]+val[u]+lmx[rs]);
rmx[u]=max(rmx[rs],sum[rs]+val[u]+rmx[ls]);
mx[u]=max(max(mx[ls],mx[rs]),rmx[ls]+val[u]+lmx[rs]);
} int build(int l,int r) {
if(r<l)return 0;
if(l==r) {
int id=dust[top--];
fix[id]=rand(),siz[id]=1;
mx[id]=val[id]=sum[id]=a[l];
lmx[id]=rmx[id]=max(0,a[l]);
return id;
}
int mid=(l+r)>>1,id=dust[top--];
fix[id]=rand(),val[id]=a[mid];
son[id][0]=build(l,mid-1);
son[id][1]=build(mid+1,r);
update(id);return id;
} void prepare() {
mx[0]=-inf;
for(int i=1;i<=500000;i++)
dust[++top]=i;
root=build(1,n);
} void make_cov_tag(int u,int v) {
if(!u)return;
cov[u]=1,val[u]=v,sum[u]=siz[u]*v;
if(v>0)mx[u]=lmx[u]=rmx[u]=sum[u];
else mx[u]=v,lmx[u]=rmx[u]=0;
} void make_rev_tag(int u) {
if(!u)return;
rev[u]^=1,swap(lmx[u],rmx[u]);
swap(son[u][0],son[u][1]);
} void push_down(int u) {
if(cov[u]) {
make_cov_tag(son[u][0],val[u]);
make_cov_tag(son[u][1],val[u]);
cov[u]=0;
}
if(rev[u]) {
make_rev_tag(son[u][0]);
make_rev_tag(son[u][1]);
rev[u]=0;
}
} pii split(int u,int rk) {
if(!rk)return make_pair(0,u);
if(rk==siz[u])return make_pair(u,0);
push_down(u);
if(siz[son[u][0]]>=rk) {
pii tmp=split(son[u][0],rk);
son[u][0]=tmp.second,update(u);
return make_pair(tmp.first,u);
}
else {
pii tmp=split(son[u][1],rk-siz[son[u][0]]-1);
son[u][1]=tmp.first,update(u);
return make_pair(u,tmp.second);
}
} int merge(int a,int b) {
if(!a||!b)return a+b;
push_down(a),push_down(b);
if(fix[a]>fix[b])return son[a][1]=merge(son[a][1],b),update(a),a;
else return son[b][0]=merge(a,son[b][0]),update(b),b;
} void ins(int pos) {
for(int i=1;i<=tot;i++)
a[i]=read();
pii tmp=split(root,pos);
root=merge(merge(tmp.first,build(1,tot)),tmp.second);
} void recycle(int u) {
if(!u)return;
dust[++top]=u;
recycle(son[u][0]),recycle(son[u][1]);
son[u][0]=son[u][1]=0,rev[u]=cov[u]=0;
} void del(int l,int r) {
pii tmp1=split(root,r);
pii tmp2=split(tmp1.first,l-1);
root=merge(tmp2.first,tmp1.second);
recycle(tmp2.second);
} void cover(int l,int r) {
int v=read();
pii tmp1=split(root,r);
pii tmp2=split(tmp1.first,l-1);
make_cov_tag(tmp2.second,v);
root=merge(merge(tmp2.first,tmp2.second),tmp1.second);
} void rever(int l,int r) {
pii tmp1=split(root,r);
pii tmp2=split(tmp1.first,l-1);
make_rev_tag(tmp2.second);
root=merge(merge(tmp2.first,tmp2.second),tmp1.second);
} int query(int l,int r) {
pii tmp1=split(root,r);
pii tmp2=split(tmp1.first,l-1);
int res=sum[tmp2.second];
root=merge(merge(tmp2.first,tmp2.second),tmp1.second);
return res;
}
}T; int main() {
srand(time(0));
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
T.prepare();
for(int i=1;i<=m;i++) {
scanf("%s",s+1);
if(s[1]!='M'||s[4]!='-')
pos=read(),tot=read();
if(s[1]=='I')T.ins(pos);
if(s[1]=='D')T.del(pos,pos+tot-1);
if(s[1]=='M'&&s[4]=='E')T.cover(pos,pos+tot-1);
if(s[1]=='R')T.rever(pos,pos+tot-1);
if(s[1]=='G')printf("%d\n",T.query(pos,pos+tot-1));
if(s[1]=='M'&&s[4]=='-')printf("%d\n",T.mx[T.root]);
}
return 0;
}

BZOJ1500:[NOI2005]维修数列的更多相关文章

  1. [BZOJ1500][NOI2005]维修数列---解题报告

    Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...

  2. [BZOJ1500][NOI2005]维修数列 解题报告 Splay

    Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...

  3. bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1500 1.覆盖标记用INF表示无覆盖标记,要求可能用0覆盖 2.代表空节点的0号节点和首尾的两个虚拟 ...

  4. [bzoj1500][NOI2005]维修数列_非旋转Treap

    维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...

  5. splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)

    先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...

  6. BZOJ1500[NOI2005]维修数列

    Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...

  7. BZOJ1500: [NOI2005]维修数列[splay ***]

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 12278  Solved: 3880[Submit][Statu ...

  8. [bzoj1500][NOI2005]维修数列——splay

    题目 题解 这道题可以说是数列问题的大BOSS,也算是这一周来学习splay等数据结构的一个总结. 我们一个一个地看这些操作. 对于操作1,我们首先建一棵子树,直接接上原树即可. 对于操作2,我们找到 ...

  9. BZOJ1500 [NOI2005]维修数列-fhq_Treap

    题面见这里 反正是道平衡树,就拿 fhq_Treap 写了写... 这道题思路基本是围绕“用 Treap 维护中序遍历” 和 中序遍历的性质 来进行的操作 所以就可以类比线段树进行一些操作 1. 建树 ...

  10. BZOJ1500: [NOI2005]维修数列 [splay序列操作]【学习笔记】

    以前写过这道题了,但我把以前的内容删掉了,因为现在感觉没法看 重写! 题意: 维护一个数列,支持插入一段数,删除一段数,修改一段数,翻转一段数,查询区间和,区间最大子序列 splay序列操作裸题 需要 ...

随机推荐

  1. u-boot-2014-04 网络不通解决一例

    不久前我移植了u-boot-214-04到Tq2440的板子上,基本功能都有了,网卡也可以使用了.有一天打算把u-boot-2010-06也也一直到tq2440上,移植完后发现u-boot-214-0 ...

  2. 深入Asyncio(四)Coroutines

    Coroutines asyncio在3.4版本添加到Python中,但通过async def和await关键字创建coroutines的语法是3.5才加入的,在这之前,人们把generators当作 ...

  3. Cesium--气泡弹窗

    参考资料 首先感谢以下博主们的帮助,本人刚接触Cesium不久,无奈只能拾人牙慧了. 由于cesium没有自带的点击弹出气泡的功能,所以需要自己去开发一个这样的功能,网络上资源很多,看到基本思路都一致 ...

  4. iOS开发 两个内存错误的一般处理方法

    本文转载至 http://blog.sina.com.cn/s/blog_a843a8850101dxlj.html 由于iOS5.0之前没有自动应用计数机制,也没有Java那样的垃圾回收功能.我们都 ...

  5. iOS与H5交互及UIWebView缓存

    iOS原生App与H5页面交互笔记 最近在做一个项目用到了原生App与H5交互,之前有做过简单的H5页面直接调用原生方法的例子,就是利用UIWebView中的代理方法 //webview每次加载之前都 ...

  6. Django创建模型_模型层

    1.在项目Mysite下创建应用bms 2.在bms下的models.py文件中创建模型 from django.db import models # Create your models here. ...

  7. Spring/Java error: namespace element 'annotation-config' … on JDK 1.5 and higher

    Extract the jar file: mkdir spring cd spring jar xvf ../spring.jar Check the Spring version in META- ...

  8. Nodejs 中常见的加密算法:RSA(1)

    Linux用户(以Ubuntu为例) $ openssl 进入OpenSSL程序 OpenSSL> genrsa -out rsa_private_key.pem 1024 生成私钥 OpenS ...

  9. map select reduce

    map: 针对每个element进行变换并返回整个修改后的map a.map do |item| a.upcase end a.map(&:upcase) 一样的效果, &:代表了it ...

  10. 协程与IO多路复用

    IO多路复用 I/O多路复用 : 通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. Python Python中有一个select模块, ...