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. HTML学习笔记之三(localstorage的使用)

    localstorage的使用 1.获取对象 var localstroage = window.localStorage; 2.存储值 localstroage.setItem('openid',' ...

  2. androidstudio连接SCM Manager上的Git库

    1.在SCM Manager里创建一个Git库 在androidstudio里选中从版本控制里导入 输入git库的地址,接下来一路点击下一步 完成之后会可以在工程里创建文件或者从别的地方把完整项目拷贝 ...

  3. Spring 链接数据库

    一.前言 Spring 现在是我们在做 JavaWeb 开发中,用的最主流的框架.以后是不是我们暂时不知道,但现在是.废话不多我就介绍 Spring 中.链接数据库的三种方式: git源码地址 需要的 ...

  4. 【java】彩票中奖码生成器:java.util.Random里的方法public int nextInt(int bound)

    package 彩票中奖码生成器; import java.util.Random; public class TestRandom { public static void main(String[ ...

  5. 数据分析与展示——Matplotlib基础绘图函数示例

    Matplotlib库入门 Matplotlib基础绘图函数示例 pyplot基础图表函数概述 函数 说明 plt.plot(x,y,fmt, ...) 绘制一个坐标图 plt.boxplot(dat ...

  6. for循环语句以及输出语句

    action() { int  i;  //定义变量    lr_start_transaction("submit_answer");  //开始事物    for(i=0; i ...

  7. iOS 正则表达式使用(转)

    1/ 教程一:认识正则表达式 .http://deerchao.net/tutorials/regex/regex.htm#mission 表7.尚未详细讨论的语法 代码/语法 说明 \a 报警字符( ...

  8. C:数据结构与算法之单链表

    单链表相对于顺序表比较难理解,但是比较实用,单链表的插入,删除不需要移动数据元素,只需要一个指针来寻找所需要的元素,还有一个大优点就是不浪费空间,当你想要增加一个结点可以申请(malloc())一个结 ...

  9. 张高兴的 Xamarin.Forms 开发笔记:Android 快捷方式 Shortcut 应用

    一.Shortcut 简介 Shortcut 是 Android 7.1 (API Level 25) 的新特性,类似于苹果的 3D Touch ,但并不是压力感应,只是一种长按菜单.Shortcut ...

  10. MySQL in or效率对比

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/60 考虑如下两个sql: select * from table ...