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

HINT

 
spaly裸题,但依旧不敢保证自己能写出来,并且有很多不会的地方
 #include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define inf 1000000000
#define N 1000005
using namespace std;
queue<int> q;
int n,m,rt,sz;
int a[N],id[N],fa[N],c[N][];
int sum[N],size[N],v[N],mx[N],lx[N],rx[N];
bool tag[N],rev[N];
void updata(int x){
int 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]);
} void pushdown(int x){
int l=c[x][],r=c[x][];
if (tag[x]){
rev[x]=tag[x]=;
if (l)tag[l]=,v[l]=v[x],sum[l]=v[x]*size[l];
if (r)tag[r]=,v[r]=v[x],sum[r]=v[x]*size[r];
if (v[x]>=){
if (l)lx[l]=rx[l]=mx[l]=sum[l];
if (r)lx[r]=rx[r]=mx[r]=sum[r];
}
else {
if (l)lx[l]=rx[l]=,mx[l]=v[l];
if (r)lx[r]=rx[r]=,mx[r]=v[r];
}
}
if (rev[x]){
rev[x]^=;rev[l]^=;rev[r]^=;
swap(lx[l],rx[l]);swap(lx[r],rx[r]);
swap(c[l][],c[l][]);swap(c[r][],c[r][]);//?
}
}
void rotate(int x,int &k){
int l,r,y=fa[x],z=fa[y];
if (c[y][]==x) l=;else l=;r=l^;
if (y==k)k=x;
else {if (c[z][]==y) c[z][]=x;else c[z][]=x;}
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
updata(y);updata(x);
} void splay(int x,int &k){
while (x!=k){
int y=fa[x],z=fa[y];
if (y!=k){
if ((c[z][]==y)^(c[y][]==x)) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
} int find(int k,int rk){
pushdown(k);
int l=c[k][],r=c[k][];
if (size[l]+==rk) return k;
if (size[l]>=rk) return find(l,rk);
return find(r,rk-size[l]-);
} int split(int k,int tot){
int x=find(rt,k),y=find(rt,k+tot+);
splay(x,rt);splay(y,c[x][]);
return c[y][];
} void build(int l,int r,int f){
if (l>r) return;
int mid=(l+r)>>,last=id[f],now=id[mid];
if (l==r){
sum[now]=a[l];size[now]=;
tag[now]=rev[now]=;
if (a[l]>=) lx[now]=rx[now]=mx[now]=a[l];
else lx[now]=rx[now]=,mx[now]=a[l];
}
else build(l,mid-,mid),build(mid+,r,mid);
v[now]=a[mid];fa[now]=last;updata(now);
c[last][mid>=f]=now;
}
void insert(int k,int tot){
for (int i=;i<=tot;i++){
if(!q.empty())id[i]=q.front(),q.pop();
else id[i]=++sz;
scanf("%d",&a[i]);
}
build(,tot,);int z=id[(+tot)>>];
int x=find(rt,k+),y=find(rt,k+);
splay(x,rt);splay(y,c[x][]);
c[y][]=z;fa[z]=y;
updata(y);updata(x);
} void rec(int x){
if (!x) return;
int l=c[x][],r=c[x][];
rec(l);rec(r);q.push(x);
fa[x]=c[x][]=c[x][]=tag[x]=rev[x]=;
} void erase(int k,int tot){
int x=split(k,tot),y=fa[x];
rec(x);c[y][]=;
updata(y);updata(fa[y]);
} void modify(int k,int tot,int val){
int x=split(k,tot),y=fa[x];
v[x]=val;tag[x]=;sum[x]=size[x]*val;
if (val>=)lx[x]=rx[x]=mx[x]=sum[x];
else lx[x]=rx[x]=,mx[x]=val;
updata(y);updata(fa[y]);
} void rever(int k,int tot){
int x=split(k,tot),y=fa[x];
if (!tag[x]){//或许会节省一点时间
rev[x]^=;
swap(c[x][],c[x][]);
swap(lx[x],rx[x]);
updata(y);updata(fa[y]);
}
} void query(int k,int tot){
int x=split(k,tot);
printf("%d\n",sum[x]);
} int main(){
scanf("%d%d",&n,&m);
mx[]=a[]=a[n+]=-inf;
for(int i=;i<=n;i++)scanf("%d",&a[i+]);
for(int i=;i<=n+;i++)id[i]=i;
build(,n+,);
rt=(n+)>>;sz=n+;
int k,tot,val;
char ch[];
while(m--)
{ //printf("%d\n",mx[rt]);
scanf("%s",ch);
if(ch[]!='M'||ch[]!='X')scanf("%d%d",&k,&tot);
if(ch[]=='I')insert(k,tot);
if(ch[]=='D')erase(k,tot);
if(ch[]=='M')
{
if(ch[]=='X')printf("%d\n",mx[rt]);
else scanf("%d",&val),modify(k,tot,val);
}
if(ch[]=='R')rever(k,tot);
if(ch[]=='G')query(k,tot);
}
return ;
}

【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. 【欧拉定理】计算(a^(b^c))%1000000007

    欧拉定理(称费马-欧拉定理或欧拉 函数定理) 欧拉定理表明,若n,a为正整数,且n,a互素(即gcd(a,n)=1),则 这个定理可以用来简化幂的模运算.比如计算7222的个位数,实际是求7222被1 ...

  2. Jersey(1.19.1) - Deploying a RESTful Web Service

    JAX-RS provides a deployment agnostic abstract class Application for declaring root resource and pro ...

  3. MySql索引的优缺点

    优点 有了索引.对于记录数量很多的表,可以提高查询速度. 缺点 索引是占用空间的. 索引会影响update insert delete速度 ALERT!!! 1.索引要创建在where和join用到的 ...

  4. django 学习-7 模型数据操作

    1.首先还是创建办一个项目和一个应用 django.admin.py   startproject    ssj cd  ssj django.admin.py   startapp    sdj 那 ...

  5. C# 计算文件的 Hash 值

    /// <summary> /// 提供用于计算指定文件哈希值的方法 /// <example>例如计算文件的MD5值: /// <code> /// String ...

  6. 函数function的方法call()以及apply()

    1.这两个方法十分重要:可以改变函数的作用域,也就是改变函数中的this     使用call()方法的时候,必须明确传入每一个参数,结果跟apply()是一样的,废话不多说,下面来一个简单的案例,便 ...

  7. Android 线程Thread的2种实现方法

    在讲解之前有以下三点要说明: 1.在Android中有两种实现线程Thread的方法: ①扩展java.long.Thread类: ②实现Runnable()接口: 2.Thread类是线程类,它有两 ...

  8. Cocos2d-x数据持久化-查询数据

    数据查询一般会带有查询条件,这可以使用SQL语句的where子句实现,但是在程序中需要动态绑定参数给where子句.查询数据的具体操作步骤如下所示.(1) 使用sqlite3_open函数打开数据库. ...

  9. NodeJS服务器退出:完成任务,优雅退出

    上一篇文章,我们通过一个简单的例子,学习了NodeJS中对客户端的请求(request)对象的解析和处理,整个文件共享的功能已经完成.但是,纵观整个过程,还有两个地方明显需要改进: 首先,不能共享完毕 ...

  10. CAD输出的局部平面坐标数据配准转换到WGS84坐标系

             局部平面坐标                                             平移纠正到常用平面坐标系下的坐标            转换后的地理坐标 采用两 ...