1500: [NOI2005]维修数列

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 15112  Solved: 4996
[Submit][Status][Discuss]

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

题解

用Splay进行区间操作的话,就要先把区间的l-1的位置旋转到根,再把r+1旋转成根的子节点

然后r+1的左子树即为所求区间

代码

//by 减维
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<map>
#include<bitset>
#include<algorithm>
#define ll long long
#define maxn 500005
#define ls son[x][0]
#define rs son[x][1]
#define inf 1<<29
using namespace std; int n,m,rt,sz,siz[maxn],son[maxn][],val[maxn],lm[maxn],rm[maxn],ma[maxn],sum[maxn];
int a[maxn],fa[maxn],cov[maxn],mark[maxn];
char ch[];
queue<int>q; bool pd(int x){return son[fa[x]][]==x;} void upda(int x)
{
if(!x)return ;
siz[x]=siz[son[x][]]+siz[son[x][]]+;
sum[x]=sum[son[x][]]+sum[son[x][]]+val[x];
ma[x]=max(max(,rm[son[x][]])+val[x]+max(,lm[son[x][]]),max(ma[son[x][]],ma[son[x][]]));
lm[x]=max(sum[son[x][]]+val[x]+max(,lm[son[x][]]),lm[son[x][]]);
rm[x]=max(sum[son[x][]]+val[x]+max(,rm[son[x][]]),rm[son[x][]]);
} int newnode(int v)
{
int s;
if(!q.empty())
s=q.front(),q.pop();
else
s=++sz;
siz[s]=;son[s][]=son[s][]=fa[s]=mark[s]=;
val[s]=sum[s]=ma[s]=lm[s]=rm[s]=v;
cov[s]=-inf;
return s;
} void rotate(int x)
{
int f=fa[x],g=fa[f],o=pd(x);
if(g)son[g][pd(f)]=x;
fa[x]=g;
son[f][o]=son[x][!o];
fa[son[f][o]]=f;
fa[f]=x;son[x][!o]=f;
upda(f);upda(x);
} void splay(int x,int tar)
{
for(;fa[x]!=tar;rotate(x))
if(fa[fa[x]]!=tar)rotate(pd(fa[x])==pd(x)?fa[x]:x);
if(tar==)rt=x;
} int build(int l,int r)
{
if(l>r)return ;
int mid=(l+r)>>;
int v=a[mid];
int now=newnode(v);
son[now][]=build(l,mid-);
son[now][]=build(mid+,r);
if(son[now][])fa[son[now][]]=now;
if(son[now][])fa[son[now][]]=now;
upda(now);
return now;
} void cover(int x,int v)
{
if(!x)return ;
cov[x]=val[x]=v;
sum[x]=v*siz[x];
lm[x]=rm[x]=ma[x]=max(v,sum[x]);
} void rever(int x)
{
if(!x)return ;
mark[x]^=;
swap(son[x][],son[x][]);
swap(lm[x],rm[x]);
} void pud(int x)
{
if(!x)return ;
if(mark[x]){
if(son[x][])rever(son[x][]);
if(son[x][])rever(son[x][]);
mark[x]=;
}
if(cov[x]!=-inf){
if(son[x][])cover(son[x][],cov[x]);
if(son[x][])cover(son[x][],cov[x]);
cov[x]=-inf;
}
} int kth(int k)
{
int x=rt;
while()
{
pud(x);
if(k<=siz[son[x][]])
x=son[x][];
else if(k==siz[son[x][]]+)
return x;
else
k-=siz[son[x][]]+,x=son[x][];
}
} void ins()
{
int pos,num;
scanf("%d%d",&pos,&num);
int l=kth(pos+),r=kth(pos+);
splay(l,);
splay(r,l);
for(int i=;i<=num;++i)scanf("%d",&a[i]);
int z=build(,num);
fa[z]=r;
son[r][]=z;
upda(z),upda(r),upda(l);
} void delt(int &x)
{
if(!x)return ;
q.push(x);
delt(son[x][]);
delt(son[x][]);
x=;
} void del()
{
int pos,num;
scanf("%d%d",&pos,&num);
int l=kth(pos),r=kth(pos+num+);
splay(l,);splay(r,l);
delt(son[r][]);
upda(r),upda(l);
} void change()
{
int pos,num,v;
scanf("%d%d%d",&pos,&num,&v);
int l=kth(pos),r=kth(pos+num+);
splay(l,);splay(r,l);
cover(son[r][],v);
upda(r),upda(l);
} void rev()
{
int pos,num;
scanf("%d%d",&pos,&num);
int l=kth(pos),r=kth(pos+num+);
splay(l,);splay(r,l);
rever(son[r][]);
upda(r),upda(l);
} void gsum()
{
int pos,num;
scanf("%d%d",&pos,&num);
int l=kth(pos),r=kth(pos+num+);
splay(l,);splay(r,l);
printf("%d\n",sum[son[r][]]);
} void dfs(int x)
{
if(!x)return ;
pud(x);
dfs(son[x][]);
printf("%d ",ma[x]);
dfs(son[x][]);
} void dfs2(int x)
{
if(!x)return ;
pud(x);
dfs2(son[x][]);
printf("%d ",val[x]);
dfs2(son[x][]);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n+;++i)scanf("%d",&a[i]);a[]=a[n+]=-inf;
siz[]=mark[]=fa[]=son[][]=son[][]=;
val[]=ma[]=lm[]=rm[]=-inf;
rt=build(,n+);
for(int i=;i<=m;++i)
{
scanf("%s",ch);
if(ch[]=='M'&&ch[]=='X'){
printf("%d\n",ma[rt]);
continue;
}
switch(ch[]){
case 'I':ins();break;
case 'D':del();break;
case 'M':change();break;
case 'R':rev();break;
case 'G':gsum();break;
}
}
return ;
}

【Splay】bzoj1500(听说此题多码上几遍就能不惧任何平衡树题)的更多相关文章

  1. 【fhq Treap】bzoj1500(听说此题多码上几遍就能不惧任何平衡树题)

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

  2. 边工作边刷题:70天一遍leetcode: day 89

    Word Break I/II 现在看都是小case题了,一遍过了.注意这题不是np complete,dp解的time complexity可以是O(n^2) or O(nm) (取决于inner ...

  3. 44个 Javascript 变态题解析 (上\下)

    第1题 ["1", "2", "3"].map(parseInt) 知识点: Array/map Number/parseInt JavaS ...

  4. noi.ac上的一套(假)NOI题

    noi.ac上的一套(假)NOI题 本来想着可以刷点通过量的,结果发现好像并不是这样的. 整数 description 给你\(n,p\),要你求\(\sum_{k=1}^n\sum_{i=1}^k\ ...

  5. Project Euler18题 从上往下邻接和

    题目:By starting at the top of the triangle below and moving to adjacent numbers on the row below, the ...

  6. 44个 Javascript 变态题解析 (上)

    原题来自: javascript-puzzlers(http://javascript-puzzlers.herokuapp.com/) 读者可以先去做一下感受感受. 当初笔者的成绩是 21/44… ...

  7. 边工作边刷题:70天一遍leetcode: day 72

    Missing Range 要点:题简单,这类题的特点都是记录上一步的状态,比如这题是end 错误点: 三种情况:一是连续的,即和上一个end差1,而是中间只差1个数,没有'->',最后是大于1 ...

  8. 土题大战Vol.0 A. 笨小猴 思维好题

    土题大战Vol.0 A. 笨小猴 思维好题 题目描述 驴蛋蛋有 \(2n + 1\) 张 \(4\) 星武器卡片,每张卡片上都有两个数字,第 \(i\) 张卡片上的两个数字分别是 \(A_i\) 与 ...

  9. 边工作边刷题:70天一遍leetcode: day 75-2

    Strobogrammatic Number I/II/III 要点:记题,注意轴对称和点对称的区别.这题就是几个固定digit之间的palindrome I https://repl.it/CqLu ...

随机推荐

  1. 独立安装WAMP

    安装apache 获得apache安装软件: 建议去官网下载: www.apache.org 双击执行: 进入欢迎界面 点击"next"进入到协议界面 接收协议点击"ne ...

  2. Memcached的安装与简单使用

    Memcached下载 如果是Win10系统,还需要单独安装telnet服务,因为Win10把它给阉掉了.(默认下一步下一步安装) 一.安装Memcached 将Memcached解压到目录,以管理员 ...

  3. Spring定时任务有时候会莫名奇妙的终止?

    最近在是使用Spring配置定时定时任务(基于xml配置使用spring自带的定时任务),一开始使用没什么问题当使用久了就会出现有些定时任务自动停止了.(关于如何使用以及如何它的原理是啥,这里不进行阐 ...

  4. IDEA定位到类的代码区域(查看类的源码)

    经常需要查看某一个类中的成员变量和方法,那么怎么进入到这个类的源码区域呢?在IDEA中只需要使用快捷键: ctrl+shift+t 就可以快速定位到这个类的源码.

  5. 关于java以及JavaScript或者更多的语言中Data类的问题

    关于java和JavaScript以及各类编程语言里Data类的月份问题,日子是从1开始数,但是星期和月份对应的周一和1月都不是1,这是为什么呢? 很多新手对此可能会不理解,老手觉得这没啥,但是我觉得 ...

  6. shell脚本小案例

    1.获取远程ftp数据到本地目录 #!/bin/bash ftp -n<<! open 135.0.24.19 user exchange exchange binary cd /idep ...

  7. linux(ubuntu) 搭建java程序运行环境

    一:简介 ubuntu 系统的和linux差不多,我们需要在系统上搭建java程序运行环境,需要安装jdk,mysql这两个软件,tomcat是绿色版,直接通过taz -zxvf tomcat 就可以 ...

  8. 「mysql优化专题」什么是慢查询?如何通过慢查询日志优化?(10)

    日志就跟人们写的日记一样,记录着过往的事情.但是人的日记是主观的(记自己想记的内容),而数据库的日志是客观的,根据记录内容分为以下好几种日志(技术文): a.错误日志:记录启动.运行或停止mysqld ...

  9. Sphinx学习笔记(一)

    最近负责一个项目,需要用到全文检索,我的环境大体如下:       1.数据保存在MySQL中     2.需要支持中文检索     3.尽可能的简单       选择了Sphinx,至于solr和E ...

  10. 48、mysql补充

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...