维修数列 bzoj-1500 NOI-2005

题目大意:给定n个数,m个操作,支持:在指定位置插入一段数;删除一个数;区间修改;区间翻转。查询:区间和;全局最大子序列。

注释:$1\le n_{max} \le 5\cdot 10^5$,$1\le m \le 2\cdot 10^4$。

想法:据说是... ...最GB的平衡树裸题,如果把这题切了,话说所有的平衡树都不怕了。

具体的,

插入和删除对于非旋转Treap来讲都是基本操作;

区间修改的话我们就先删除然后插入即可;

区间反转就打标记;

区间和就是单点维护子树和;

全局最大子序列的话像小白逛公园一样维护一下从左右开始的最长子序列。

最后,附上丑陋的代码... ...

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 502333
#define MAXN 4002333
using namespace std;
char c;int v;
inline void read(int &x)
{
x=0;c=getchar();v=1;
while(c<'0'||c>'9')
{
if(c=='-')v=-1;
c=getchar();
}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
x*=v;
}
int n,m,root;
struct Node
{
int ls,rs,size,key,val,sum,maxx,lmax,rmax,f;
bool turn;
}a[N];
struct par{int x,y;};
int q[MAXN],l=1,r,cnt,temp[N];
inline void clear(int x)
{
a[x].ls=a[x].rs=a[x].size=a[x].key=a[x].val=0;
a[x].maxx=a[x].lmax=a[x].rmax=a[x].turn=0;
a[x].f=2333;
}
inline void update(int x)
{
int ls=a[x].ls,rs=a[x].rs;
a[x].size=1;a[x].maxx=a[x].sum=a[x].val;
if(ls)a[x].size+=a[ls].size,a[x].sum+=a[ls].sum,a[x].maxx=max(a[x].maxx,a[ls].maxx);
if(rs)a[x].size+=a[rs].size,a[x].sum+=a[rs].sum,a[x].maxx=max(a[x].maxx,a[rs].maxx);
a[x].maxx=max(a[x].maxx,a[ls].rmax+a[x].val+a[rs].lmax);
a[x].lmax=max(a[ls].lmax,a[ls].sum+a[x].val+a[rs].lmax);
a[x].rmax=max(a[rs].rmax,a[rs].sum+a[x].val+a[ls].rmax);
}
inline void pushdown(int x)
{
if(!x)return;
int ls=a[x].ls,rs=a[x].rs;
if(a[x].turn)
{
if(ls)
{
a[ls].turn^=1;
swap(a[ls].lmax,a[ls].rmax);
}
if(rs)
{
a[rs].turn^=1;
swap(a[rs].lmax,a[rs].rmax);
}
swap(a[x].ls,a[x].rs);
a[x].turn=0;
}
ls=a[x].ls,rs=a[x].rs;
if(a[x].f!=2333)
{
if(ls)
{
a[ls].f=a[ls].val=a[x].f;a[ls].sum=a[ls].size*a[ls].f;
if(a[ls].f>0)a[ls].maxx=a[ls].lmax=a[ls].rmax=a[ls].sum;
else a[ls].maxx=a[ls].f,a[ls].lmax=a[ls].rmax=0;
}
if(rs)
{
a[rs].f=a[rs].val=a[x].f;a[rs].sum=a[rs].size*a[rs].f;
if(a[rs].f>0)a[rs].maxx=a[rs].lmax=a[rs].rmax=a[rs].sum;
else a[rs].maxx=a[rs].f,a[rs].lmax=a[rs].rmax=0;
}
a[x].f=2333;
}
}
int merge(int x,int y)
{
if(!x||!y)return x|y;
pushdown(x),pushdown(y);
if(a[x].key>a[y].key)
{
a[x].rs=merge(a[x].rs,y);update(x);
return x;
}
a[y].ls=merge(x,a[y].ls);update(y);
return y;
}
par split(int x,int k)
{
if(!k)return (par){0,x};
pushdown(x);
int ls=a[x].ls,rs=a[x].rs;
if(k==a[ls].size)
{
a[x].ls=0;update(x);
return (par){ls,x};
}
if(k==a[ls].size+1)
{
a[x].rs=0;update(x);
return (par){x,rs};
}
if(k<a[ls].size)
{
par t=split(ls,k);
a[x].ls=t.y;update(x);
return (par){t.x,x};
}
par t=split(rs,k-a[ls].size-1);
a[x].rs=t.x;update(x);
return (par){x,t.y};
}
inline int makenew(int x)
{
int p;
if(l<=r)p=q[l++];
else p=++cnt;
a[p].size=1,a[p].maxx=a[p].sum=a[p].val=x;
a[p].lmax=a[p].rmax=max(x,0);
a[p].turn=0,a[p].f=2333;
a[p].key=rand();
return p;
}
int build(int L,int R)
{
if(L==R)return makenew(temp[L]);
int mid=(L+R)>>1;
return merge(build(L,mid),build(mid+1,R));
}
void del(int x)
{
if(!x)return;
del(a[x].ls);
del(a[x].rs);
clear(x);
q[++r]=x;
}
int main()
{
read(n),read(m);
for(int i=1;i<=n;i++)read(temp[i]);
root=build(1,n);
char flag[10];
for(int x,num,val,j,i=1;i<=m;i++)
{
scanf("%s",flag);
if(flag[0]=='I')
{
read(x);read(num);
for(j=1;j<=num;j++)read(temp[j]);
par t=split(root,x);
root=merge(merge(t.x,build(1,num)),t.y);
}
else if(flag[0]=='D')
{
read(x);read(num);x--;
par t1=split(root,x),t2=split(t1.y,num);
del(t2.x);
root=merge(t1.x,t2.y);
}
else if(flag[0]=='R')
{
read(x);read(num);x--;
par t1=split(root,x),t2=split(t1.y,num);
a[t2.x].turn^=1;swap(a[t2.x].lmax,a[t2.x].rmax);
root=merge(t1.x,merge(t2.x,t2.y));
}
else if(flag[0]=='G')
{
read(x);read(num);x--;
par t1=split(root,x),t2=split(t1.y,num);
printf("%d\n",a[t2.x].sum);
root=merge(t1.x,merge(t2.x,t2.y));
}
else if(flag[2]=='X')printf("%d\n",a[root].maxx);
else
{
read(x);read(num);read(val);x--;
par t1=split(root,x),t2=split(t1.y,num);
a[t2.x].f=a[t2.x].val=val;a[t2.x].sum=val*a[t2.x].size;
if(val>0)a[t2.x].maxx=a[t2.x].lmax=a[t2.x].rmax=a[t2.x].sum;
else a[t2.x].maxx=val,a[t2.x].lmax=a[t2.x].rmax=0;
root=merge(t1.x,merge(t2.x,t2.y));
}
}
return 0;
}

小结:裸题就是开心... ...

P.S.:非旋转Treap就是比splay优越!

[bzoj1500][NOI2005]维修数列_非旋转Treap的更多相关文章

  1. 2018.08.06 bzoj1500: [NOI2005]维修数列(非旋treap)

    传送门 平衡树好题. 我仍然是用的fhqtreap,感觉速度还行. 维护也比线段树splay什么的写起来简单. %%%非旋treap大法好. 代码: #include<bits/stdc++.h ...

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

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

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

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

  4. BZOJ1500[NOI2005]维修数列——非旋转treap

    题目描述 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格 输入 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初 ...

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

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

  6. [bzoj3173]最长上升子序列_非旋转Treap

    最长上升子序列 bzoj-3173 题目大意:有1-n,n个数,第i次操作是将i加入到原有序列中制定的位置,后查询当前序列中最长上升子序列长度. 注释:1<=n<=10,000,开始序列为 ...

  7. [bzoj4864][BeiJing2017Wc]神秘物质_非旋转Treap

    神秘物质 bzoj-4864 BeiJing-2017-Wc 题目大意:给定一个长度为n的序列,支持插入,将相邻两个元素合并并在该位置生成一个指定权值的元素:查询:区间内的任意一段子区间的最大值减最小 ...

  8. [bzoj1552\bzoj2506][Cqoi2014]robotic sort 排序机械臂_非旋转Treap

    robotic sort 排序机械臂 bzoj-1552 bzoj-2506 Cqoi-2014 题目大意:给定一个序列,让你从1到n,每次将[1,p[i]]这段区间反转,p[i]表示整个物品权值第i ...

  9. [bzoj1861][Zjoi2006]Book 书架_非旋转Treap

    Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...

随机推荐

  1. Linux framebuffer显示bmp图片【转】

    本文转载自:http://blog.csdn.net/luxiaoxun/article/details/7622988 framebuffer简介 帧缓冲(framebuffer)是Linux为显示 ...

  2. 此文章介绍vue-cli脚手架config目录下index.js配置文件

    此配置文件是用来定义开发环境和生产环境中所需要的参数 关于注释 当涉及到较复杂的解释我将通过标识的方式(如(1))将解释写到单独的注释模块,请自行查看 上代码 // see http://vuejs- ...

  3. 安装Windows包管理工具Chocolatey

    1.开始菜单里面用PS的管理员模式打开,执行一下命令. Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object Syste ...

  4. jorgchart,帮助你生成组织结构图的

    下载地址: http://yunpan.cn/c6pfenkmmFV2q  访问密码 8e29 演示链接: http://www.gbtags.com/gb/share/546.htm jstree. ...

  5. # 深入理解Redis(二)——内存管理的建议与技巧

    引语 随着使用Redis的深入,我们不可避免的需要深入了解优化Redis的内存,本章将重点讲解Redis的内存优化之道,同时推荐大家阅读memory-optimization一文. 想要高效的使用Re ...

  6. Spring Boot (19) servlet、filter、listener

    servlet.filter.listener,在spring boot中配置方式有两种:一种是以servlet3开始提供的注解方式,另一种是spring的注入方式. servlet注解方式 serv ...

  7. android开源新闻小程序、3D翻转公告效果、小说检索、Kotlin开发TODO清单等源码

    Android精选源码 开源新闻小程序源码分享 android动态壁纸.锁屏动画.来电秀等源码 android笔记App效果源码 Android实现3D版翻页公告效果 android小说搜索阅读源码 ...

  8. PL/SQL之高级篇

    原文地址:http://www.cnblogs.com/sin90lzc/archive/2012/08/30/2661117.html 参考文献:<Oracle完全学习手册> 1.概述 ...

  9. SLAM: 单目视觉SLAM的方案分类《机器人手册》

    摘抄知乎上一段有趣的话:     如果你出门问别人『学习SLAM需要哪些基础?』之类的问题,一定会有很热心的大哥大姐过来摸摸你的头,肩或者腰(不重要),一脸神秘地从怀里拿出一本比馒头还厚的<Mu ...

  10. (转)基于Metronic的Bootstrap开发框架经验总结(4)--Bootstrap图标的提取和利用

    http://www.cnblogs.com/wuhuacong/p/4762924.html 在前面的一篇随笔<基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模 ...