Description

Input

输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

Output

对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

Sample Input

9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM

Sample Output

-1
10
1
10

题解:

平衡树的模板题,要用上翻转标记、统一赋值标记,维护区间和、区间最大左子串、区间最大右子串、区间最大子串。

代码:

 var
n,m,rt,cnt,i,j,k,tot,vall,ql,qr:longint;
a,id,fa,sum,size,v,mx,lx,rx,tag,rev:array[..]of longint;
c:array[..,..]of longint;
q:array[..]of longint;
ch:array[..]of char;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
procedure update(x:longint);
var l,r:longint;
begin
l:=c[x,]; r:=c[x,];
sum[x]:=sum[l]+sum[r]+v[x];
size[x]:=size[l]+size[r]+;
mx[x]:=max(mx[l],mx[r]);
mx[x]:=max(mx[x],rx[l]+v[x]+lx[r]);
lx[x]:=max(lx[l],sum[l]+v[x]+lx[r]);
rx[x]:=max(rx[r],sum[r]+v[x]+rx[l]);
end;
procedure pushdown(x:longint);
var l,r,ttt:longint;
begin
l:=c[x,]; r:=c[x,];
if tag[x]> then
begin
tag[x]:=; rev[x]:=;
if l> then begin tag[l]:=; v[l]:=v[x]; sum[l]:=v[x]*size[l]; end;
if r> then begin tag[r]:=; v[r]:=v[x]; sum[r]:=v[x]*size[r]; end;
if v[x]>= then
begin
if l> then begin mx[l]:=sum[l]; rx[l]:=sum[l]; lx[l]:=sum[l]; end;
if r> then begin mx[r]:=sum[r]; rx[r]:=sum[r]; lx[r]:=sum[r]; end;
end else
begin
if l> then begin lx[l]:=; rx[l]:=; mx[l]:=v[x]; end;
if r> then begin lx[r]:=; rx[r]:=; mx[r]:=v[x]; end;
end;
end;
if rev[x]> then
begin
rev[x]:=rev[x] xor ; rev[l]:=rev[l] xor ; rev[r]:=rev[r] xor ;
ttt:=lx[l]; lx[l]:=rx[l]; rx[l]:=ttt; ttt:=lx[r]; lx[r]:=rx[r]; rx[r]:=ttt;
ttt:=c[l,]; c[l,]:=c[l,]; c[l,]:=ttt; ttt:=c[r,]; c[r,]:=c[r,]; c[r,]:=ttt;
end;
end;
procedure rotate(x:longint;var k:longint);
var y,z,l,r:longint;
begin
y:=fa[x]; z:=fa[y];
if c[y,]=x then l:= else l:=; r:=l xor ;
if y=k then k:=x
ELSE BEGIN if c[z,]=y then c[z,]:=x else c[z,]:=x; END;
fa[c[x,r]]:=y; fa[y]:=x; fa[x]:=z;
c[y,l]:=c[x,r]; c[x,r]:=y;
update(y); update(x);
end;
procedure splay(x:longint; var k:longint);
var y,z:longint;
begin
while x<>k do
begin
y:=fa[x]; z:=fa[y];
if y<>k then
begin
if(c[y,]=x)xor(c[z,]=y)then rotate(x,k)
else rotate(y,k);
end;
rotate(x,k);
end;
end;
function find(x,rk:longint):longint;
var l,r:longint;
begin
pushdown(x);
l:=c[x,]; r:=c[x,];
if size[l]+=rk then exit(x);
if size[l]>=rk then exit(find(l,rk));
exit(find(r,rk-size[l]-));
end;
procedure rec(x:longint);
var l,r:longint;
begin
if x= then exit;
l:=c[x,]; r:=c[x,];
rec(l); rec(r); inc(qr); if qr= then qr:=; q[qr]:=x;
fa[x]:=; c[x,]:=; c[x,]:=;
tag[x]:=; rev[x]:=;
end;
function split(k,tot:longint):longint;
var x,y:longint;
begin
x:=find(rt,k); y:=find(rt,k+tot+);
splay(x,rt); splay(y,c[x,]);
exit(c[y,]);
end;
procedure query(k,tot:longint);
var x:longint;
begin
x:=split(k,tot);
writeln(sum[x]);
end;
procedure modify(k,tot,vall:longint);
var x,y,I:longint;
begin
x:=split(k,tot); y:=fa[x];
v[x]:=vall; tag[x]:=; sum[x]:=size[x]*vall;
if vall>= then begin lx[x]:=sum[x]; rx[x]:=sum[x]; mx[x]:=sum[x]; end
else begin lx[x]:=; rx[x]:=; mx[x]:=vall; end;
update(y); update(fa[y]);
end;
procedure rever(k,tot:longint);
var x,y,ttt:longint;
begin
x:=split(k,tot); y:=fa[x];
if tag[x]= then
begin
rev[x]:=rev[x]xor ;
ttt:=c[x,]; c[x,]:=c[x,]; c[x,]:=ttt;
ttt:=lx[x]; lx[x]:=rx[x]; rx[x]:=ttt;
update(y); update(fa[y]);
end;
end;
procedure erase(k,tot:longint);
var x,y:longint;
begin
x:=split(k,tot); y:=fa[x];
rec(x); c[y,]:=;
update(y); update(fa[y]);
end;
procedure build(l,r,f:longint);
var mid,now,last:longint;
begin
if l>r then exit;
mid:=(l+r)div ; now:=id[mid]; last:=id[f];
if l=r then
begin
sum[now]:=a[l]; size[now]:=;
tag[now]:=; rev[now]:=;
if a[l]>= then begin lx[now]:=a[l]; rx[now]:=a[l]; mx[now]:=a[l]; end
else begin lx[now]:=; rx[now]:=; mx[now]:=a[l]; end;
end else begin build(l,mid-,mid); build(mid+,r,mid); end;
v[now]:=a[mid]; fa[now]:=last; update(now);
if mid>=f then c[last,]:=now else c[last,]:=now;
end;
procedure insert(k,tot:longint);
var i,z,x,y:longint;
begin
for i:= to tot do read(a[i]);
for i:= to tot do
if(ql<>qr)then begin inc(ql); if ql= then ql:=; id[i]:=q[ql]; end
else begin inc(cnt); id[i]:=cnt; end;
build(,tot,); z:=id[(+tot)div ];
x:=find(rt,k+); y:=find(rt,k+);
splay(x,rt); splay(y,c[x,]);
fa[z]:=y; c[y,]:=z;
update(y); update(x);
end;
begin
readln(n,m); mx[]:=-; a[]:=-; a[n+]:=-;
for i:= to n do read(a[i+]); readln;
for i:= to n+ do id[i]:=i;
build(,n+,);
rt:=(n+)div ; cnt:=n+;
for i:= to m do
begin
read(ch[],ch[],ch[]);
read(ch[]); while(not eoln)and(ch[]<>' ')do read(ch[]);
if(ch[]<>'M')or(ch[]<>'X')then begin read(k,tot); end;
if ch[]='I' then insert(k,tot);
if ch[]='D' then erase(k,tot);
if ch[]='M' then
begin
if ch[]='X' then writeln(mx[rt])
else begin read(vall); modify(k,tot,vall); end;
end;
if ch[]='R' then rever(k,tot);
if ch[]='G' then query(k,tot);
readln;
end;
end.

PASCAL(Splay)

 #include<bits/stdc++.h>
using namespace std;
int tr[][],fa[],a[],root,cnt,n,m,j,k,l,ql,qr,q[];
char s[];
int newt(int v)
{
int x; if(ql!=qr){ ql++; if(ql>)ql=; x=q[ql]; }else x=++cnt;
tr[x][]=tr[x][]=tr[x][]=; tr[x][]=-;
tr[x][]=; tr[x][]=tr[x][]=tr[x][]=v; tr[x][]=tr[x][]=max(,v);
return x;
}
void up(int x)
{
int l=tr[x][],r=tr[x][];
tr[x][]=tr[l][]+tr[r][]+; tr[x][]=tr[l][]+tr[r][]+tr[x][];
tr[x][]=max(max(tr[l][],tr[r][]),tr[l][]+tr[x][]+tr[r][]);
tr[x][]=max(tr[l][],tr[l][]+tr[x][]+tr[r][]); tr[x][]=max(tr[r][],tr[l][]+tr[x][]+tr[r][]);
}
void down(int x)
{
if(x==)return;
int l=tr[x][],r=tr[x][]; if(l==)l=; if(r==)r=;
int x1=tr[x][],x2=tr[x][]; tr[x][]=-; tr[x][]=;
if(x1>-)
{
tr[l][]=tr[r][]=tr[l][]=tr[r][]=x1; tr[l][]=tr[l][]*x1; tr[r][]=tr[r][]*x1;
if(x1>=)
{
tr[l][]=tr[l][]=tr[l][]=tr[l][];
tr[r][]=tr[r][]=tr[r][]=tr[r][];
}else tr[l][]=tr[r][]=x1,tr[l][]=tr[l][]=tr[r][]=tr[r][]=;
}else
if(x2==)
{
tr[l][]^=; tr[r][]^=;
swap(tr[l][],tr[l][]); swap(tr[r][],tr[r][]);
swap(tr[l][],tr[l][]); swap(tr[r][],tr[r][]);
}
}
void del(int x)
{
if(x==)return;
qr++; if(qr>)qr=; q[qr]=x;
del(tr[x][]); del(tr[x][]);
}
int build(int l,int r)
{
int mid=(l+r)/; int x=newt(a[mid]);
if(l<mid)tr[x][]=build(l,mid-);
fa[tr[x][]]=x;
if(mid<r)tr[x][]=build(mid+,r);
fa[tr[x][]]=x;
up(x); return x;
}
pair<int,int> fl(int x,int y)
{
if(x==)return make_pair(,);
down(x);
if(tr[tr[x][]][]>=y)
{
pair<int,int> a=fl(tr[x][],y);
fa[a.second]=x; tr[x][]=a.second; up(x); a.second=x; return a;
}else
{
pair<int,int> a=fl(tr[x][],y-tr[tr[x][]][]-);
fa[a.first]=x; tr[x][]=a.first; up(x); a.first=x; return a;
}
}
int hb(int x,int y)
{
if(x==)return y; if(y==)return x;
down(x); down(y);
if(1ll*rand()*(tr[x][]+tr[y][])<1ll*RAND_MAX*tr[x][]){ int a=hb(tr[x][],y); fa[a]=x; tr[x][]=a; up(x); return x; }
int a=hb(x,tr[y][]); fa[a]=y; tr[y][]=a; up(y); return y;
}
int find(int x,int y)
{
down(x);
if(tr[tr[x][]][]>=y)return find(tr[x][],y);
if(tr[tr[x][]][]+==y)return x;
return find(tr[x][],y-tr[tr[x][]][]-);
}
int main()
{
srand();
scanf("%d%d",&n,&m); tr[][]=-/;
for(int i=;i<=n;i++)scanf("%d",&a[i]);
root=build(,n);
for(int i=;i<=m;i++)
{
scanf("%s",s+);
if(s[]=='I')
{
scanf("%d%d",&k,&n);
for(int j=;j<=n;j++)scanf("%d",&a[j]); int x=build(,n);
pair<int,int> a=fl(root,k); root=hb(hb(a.first,x),a.second);
}else
if(s[]=='D')
{
scanf("%d%d",&j,&k);
pair<int,int> a=fl(root,j-); pair<int,int> b=fl(a.second,k);
root=hb(a.first,b.second); del(b.first);
}else
if((s[]=='M')and(s[]=='K'))
{
scanf("%d%d%d",&j,&k,&l);
pair<int,int> a=fl(root,j-); pair<int,int> b=fl(a.second,k);
int x=b.first; tr[x][]=tr[x][]=l; tr[x][]=tr[x][]*l;
if(l>=)tr[x][]=tr[x][]=tr[x][]=tr[x][];else tr[x][]=l,tr[x][]=tr[x][]=;
root=hb(hb(a.first,x),b.second);
}else
if(s[]=='R')
{
scanf("%d%d",&j,&k);
pair<int,int> a=fl(root,j-); pair<int,int> b=fl(a.second,k);
int x=b.first; tr[x][]^=; swap(tr[x][],tr[x][]); swap(tr[x][],tr[x][]);
root=hb(hb(a.first,x),b.second);
}else
if(s[]=='G')
{
scanf("%d%d",&j,&k);
pair<int,int> a=fl(root,j-); pair<int,int> b=fl(a.second,k);
int x=b.first; printf("%d\n",tr[x][]); root=hb(hb(a.first,x),b.second);
}else printf("%d\n",tr[root][]);
}
}

C++(非旋转式Treap)

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]维修数列[splay ***]

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

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

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

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

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

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

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

随机推荐

  1. 原创:去繁存简,回归本源:微信小程序公开课信息分析《一》

    以前我开过一些帖子,我们内部也做过一些讨论,我们从张小龙的碎屏图中 ,发现了重要讯息: 1:微信支付将成为重要场景: 2:这些应用与春节关系不小,很多应用在春节时,有重要的场景开启可能性: 3:春节是 ...

  2. Mybatis框架 的快速入门

    MyBatis 简介 什么是 MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果 ...

  3. java继承覆盖与向上转型,权限

    子类可以覆盖父类的非final成员变量和重写非final方法 private私有变量和方法只能在类的内部使用,因此子类继承的同时会被隐藏,相当于不继承 protected变量,子类可以继承调用 方法被 ...

  4. ASP.NET Core 中文文档 第三章 原理(8)日志

    原文:Logging 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:何镇汐.许登洋(Seay) ASP.NET Core 内建支持日志,也允许开发人员轻松切换为他们想用的其他日 ...

  5. “NOSQL” 杂谈

    引言: nosql 的兴起和革命,在我看来已经开始逐渐影响到了传统的sql的地位,但是仅仅是影响而已,取代是不太可能的. 正文: 两年前,一个偶然的机会开始接触到 nosql ( mongodb ). ...

  6. CSS常见居中讨论

    先来一个常见的案例,把一张图片和下方文字进行居中: 首先处理左右居中,考虑到img是一个行内元素,下方的文字内容也是行内元素,因此直接用text-align即可: <style> .con ...

  7. 精彩 JavaScript 代码片段

    1. 根据给定的条件在原有的数组上,得到所需要的新数组. ——<JavaScript 王者归来> var a = [-1,-1,1,2,-2,-2,-3,-3,3,-3]; functio ...

  8. 基于 Cmd MarkDown 的 markdown 语法学习

    首先我要打一个属于干货的广告:CmdMarkDown 是非常好用的markdown编辑器软件,支持全平台,由作业部落出品,分为客户端与WEB端两种使用场景. 本篇博客学习的markdown语法都是基于 ...

  9. 设计模式(八)桥接模式(Bridge Pattern)

    一.引言 这里以电视遥控器的一个例子来引出桥接模式解决的问题,首先,我们每个牌子的电视机都有一个遥控器,此时我们能想到的一个设计是——把遥控器做为一个抽象类,抽象类中提供遥控器的所有实现,其他具体电视 ...

  10. C# - 集合类

    C#的集合类命名空间介绍: // 程序集 mscorlib.dll System.dll System.Core.dll // 命名空间 using System.Collections:集合的接口和 ...