维修数列 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. 洛谷 P3953 [ NOIP 2017 ] 逛公园 —— 最短路DP

    题目:https://www.luogu.org/problemnew/show/P3953 主要是看题解...还是觉得好难想啊... dfs DP,剩余容量的损耗是边权减去两点最短路差值...表示对 ...

  2. python使用MySQLdb向mySQL批量插入数据的方法

    该功能通过调用mySQLdb python库中的 cursor.executemany()函数完成批量处理. 今天用这个函数完成了批量插入 例程: def test_insertDB(options) ...

  3. Grafana+Zabbix+Prometheus 监控系统

    环境说明 软件 版本 操作系统 IP地址 Grafana 5.4.3-1 Centos7.5 192.168.18.231 Prometheus 2.6.1 Centos7.5 192.168.18. ...

  4. Win7的虚拟Wi-Fi

    前几天无意中发现,Win7的硬件驱动里有个叫Microsoft Virtual WiFi Miniport Adapter的东东,从网上查了一下,可以用来组建临时网络,共享Internet.一块无线网 ...

  5. Serializable资料整理

    1. 序列化 简单的说就是为了保存 内存中各种对象的状态(是实例变量,不是方法),并且可以把保存的对象读取出来. 虽然保存 object states的方法很多,但是Java提供了一种保存对象状态的机 ...

  6. dubbo之回声测试

    回声测试 回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控. 所有服务自动实现 EchoService 接口,只需将任意服务引用强制转型为 EchoSe ...

  7. Windows 10 新功能

    一.与 Cortana 集成的便笺 借助便笺,你可捕捉并保存绝妙创意或记录重要细节.便笺现已与 Cortana 集成,让你能够设置整个设备中的提醒. (一)   先来了解一下微软小娜Cortana. ...

  8. 【Hexo】deploy出错的解决方法

    .ERROR Deployer not found: git 执行npm install hexo-deployer-git --save .$ hexo d INFO Deploying: git ...

  9. C# 截取字符串基本

    #region --构建字符串处理 string str1 = "123AAA456AAAA789AAAAAAA1011"; string str2 = "1234567 ...

  10. js DOM 节点树 设置 style 样式属性

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...