BZOJ1500[NOI2005]维修数列
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
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
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]维修数列的更多相关文章
- [BZOJ1500][NOI2005]维修数列---解题报告
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- [BZOJ1500][NOI2005]维修数列 解题报告 Splay
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)
http://www.lydsy.com/JudgeOnline/problem.php?id=1500 1.覆盖标记用INF表示无覆盖标记,要求可能用0覆盖 2.代表空节点的0号节点和首尾的两个虚拟 ...
- [bzoj1500][NOI2005]维修数列_非旋转Treap
维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...
- splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)
先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...
- BZOJ1500: [NOI2005]维修数列[splay ***]
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 12278 Solved: 3880[Submit][Statu ...
- [bzoj1500][NOI2005]维修数列——splay
题目 题解 这道题可以说是数列问题的大BOSS,也算是这一周来学习splay等数据结构的一个总结. 我们一个一个地看这些操作. 对于操作1,我们首先建一棵子树,直接接上原树即可. 对于操作2,我们找到 ...
- BZOJ1500 [NOI2005]维修数列-fhq_Treap
题面见这里 反正是道平衡树,就拿 fhq_Treap 写了写... 这道题思路基本是围绕“用 Treap 维护中序遍历” 和 中序遍历的性质 来进行的操作 所以就可以类比线段树进行一些操作 1. 建树 ...
- BZOJ1500: [NOI2005]维修数列 [splay序列操作]【学习笔记】
以前写过这道题了,但我把以前的内容删掉了,因为现在感觉没法看 重写! 题意: 维护一个数列,支持插入一段数,删除一段数,修改一段数,翻转一段数,查询区间和,区间最大子序列 splay序列操作裸题 需要 ...
随机推荐
- Hibernate中的锁机制
锁机制:是数据库为了保证数据的一致性<一个事务的各种操作不相互影响>而使各种共享资源在被并发访问访问变得有序所设计的一种规则,用来保证在当前用户进行操作数据的时候其他的用户不能对同一数据进 ...
- ashx中Response.ContentType的常用类型
ashx中Response.ContentType的常用类型: text/plaintext/htmltext/xmlapplication/jsonimage/GIFapplication/x-cd ...
- 学习SpringMVC——说说视图解析器
各位前排的,后排的,都不要走,咱趁热打铁,就这一股劲我们今天来说说spring mvc的视图解析器(不要抢,都有位子~~~) 相信大家在昨天那篇如何获取请求参数篇中都已经领略到了spring mvc注 ...
- 跨域之同源策略 Same-origin policy
同源策略是浏览器中最基本的隔离潜在恶意文件的安全策略,他限制了来自不同源(origin)的文档或脚本之间的相互作用. 何谓同源 在跨域之URL中介绍过一个URL的标准格式如下: 协议类型://服务器地 ...
- Moon.Orm 常见查询实例
一.Moon.Orm框架总述 (您还用hibernate?实体框架?) 1.框架名:Moon 意思是月亮,而非Mono.因为很喜欢明月,所以以此为名.它是一个.NET下的Orm框架. 2.发展历史:历 ...
- new/delete重载
在c++中,有时我们需要在运行阶段为一个变量分配未命名的内存,并使用指针来访问它,这里就可以用到new关键字.另外需要指出的是,new分配的内存块通常与常规变量分配的内存块不同,常规变量的值都储存在被 ...
- CSS布局 - 三栏布局
CSS布局技术可谓是前端技术中最基础的技术,就是因为基础,所以我认为要更加熟练,深入的去掌握,去梳理. 一. 传统 ---> 浮动实现的三栏布局 采用浮动实现的三栏布局有以下特点及注意事项: · ...
- C#开发微信门户及应用(3)--文本消息和图文消息的应答
微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下.学习下微信的相关开发,也就成为计划的安排事情之一了.本系列文章希望从一个循序渐进的角度上,全面介绍微 ...
- 简述9种社交概念 SNS究竟用来干嘛?
1.QQ 必备型交流工具基本上每一个网民最少有一个QQ,QQ已经成为网民的标配,网络生活中已经离不开QQ了.虽然大家嘴上一直在骂 QQ这个不好,那个不对,但是很少有人能彻底离开QQ.QQ属于IM软件, ...
- python之最强王者(6)——列表(List)
1.Python 列表(List) 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置 ...