真的是太弱了TAT。。。光是把代码码出来就花了3h。。还调了快1h才弄完T_T

号称考你会不会splay(当然通过条件是1h内AC。。吓傻)。。。

黄学长的题解:http://hzwer.com/2841.html

当然了蒟蒻的splay模板全部都是借(抄)鉴(袭)黄学长的。。。。

主要是注意任何对子树的修改一定要记得pushup一定要记得pushup一定要记得pushup。。。计算最大子段和和bzoj1858一个姿势,就是维护子树的最大子段和,从左和从右开始的最大子段和(当然了平衡树和线段树在这里还是有点区别的);

对于修改和翻转可以打懒标记。。。插入的话可以先把要插入的数建出一颗splay树,然后把新树和原来的树连起来;

为了避免判断区间边界啊什么的可以多建两个边界节点。。。

据说要加上垃圾回收,这样的话还要新开一个id数组用来存节点的编号,那样的话数组开到50w就可以了。。

如果不要垃圾回收的话,删除时把对应区间的子树与原来的树断开连接就好了,垃圾回收还得把要砍掉的子树里面的节点遍历重置。。。oj上没写数据范围让人感觉有点虚。。

 #include<stdio.h>
#include<math.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=;
const int maxn=;//题目又没说数据范围= =//经测试加了垃圾优化开50w就好了= =
struct zs{
int c[],fa,mx,lmx,rmx,val,size,sum;
bool change,rev;
}tree[maxn];
queue<int>q;
int a[maxn],id[maxn];
char iid[];
int i,j,k,n,m,cnt,tot,x,c,root;
void update(int now){
int l=tree[now].c[],r=tree[now].c[];
tree[now].size=tree[l].size+tree[r].size+;
tree[now].sum=tree[l].sum+tree[r].sum+tree[now].val;
tree[now].mx=max(tree[l].mx,tree[r].mx);
tree[now].mx=max(tree[now].mx,tree[l].rmx+tree[now].val+tree[r].lmx);
tree[now].lmx=max(tree[l].lmx,tree[l].sum+tree[now].val+tree[r].lmx);
tree[now].rmx=max(tree[r].rmx,tree[r].sum+tree[now].val+tree[l].rmx);
}
void deal(int now,bool change,bool rev,int val){
if(change){
tree[now].change=;
tree[now].val=val;
tree[now].sum=tree[now].size*val;
if(val>)
tree[now].mx=tree[now].lmx=tree[now].rmx=tree[now].sum;
else tree[now].mx=val,tree[now].lmx=tree[now].rmx=;
}
else//如果整段覆盖了翻不翻转都一样
if(rev){
tree[now].rev^=;
// printf("! %d %d %d\n",now,tree[now].c[0],tree[now].c[1]);
swap(tree[now].c[],tree[now].c[]);
swap(tree[now].lmx,tree[now].rmx);
}
}
void pushdown(int now){
int l=tree[now].c[],r=tree[now].c[];
if(l)deal(l,tree[now].change,tree[now].rev,tree[now].val);
if(r)deal(r,tree[now].change,tree[now].rev,tree[now].val);
tree[now].change=tree[now].rev=;
}
void build(int l,int r,int premid){
int now,mid,fa;
if(l>r)return;
mid=(l+r)>>;
fa=id[premid];now=id[mid];//本来id[i]==i,但因为垃圾回收。。。
if(mid<premid)tree[fa].c[]=now;else tree[fa].c[]=now;
tree[now].fa=fa;
tree[now].val=a[mid];
if(l<r){
build(l,mid-,mid);build(mid+,r,mid);
update(now);
}else{
// printf(" !%d %d\n",now,tree[now].val);
tree[now].size=;
tree[now].mx=tree[now].sum=tree[now].val;
if(tree[now].val>)tree[now].lmx=tree[now].rmx=tree[now].mx;
else tree[now].lmx=tree[now].rmx=;
}
// printf("! %d %d %d %d %d %d %d %d\n",now,tree[now].c[0],tree[now].c[1],tree[now].mx,tree[now].lmx,tree[now].rmx,tree[now].change,tree[now].rev);
}
void rotate(int now,int&root){
int fa,gfa,l,r;
fa=tree[now].fa;gfa=tree[fa].fa;
if(fa==root)root=now;
else tree[gfa].c[tree[gfa].c[]!=fa]=now;
if(tree[fa].c[]==now)l=;else l=;
r=l^;
tree[now].fa=gfa;tree[fa].fa=now;
tree[fa].c[l]=tree[now].c[r];tree[now].c[r]=fa;
tree[tree[fa].c[l]].fa=fa;
update(fa);update(now);
}
void splay(int now,int&root){
int fa,gfa;
while(now!=root){
fa=tree[now].fa;gfa=tree[fa].fa;
if(fa!=root)
if((tree[fa].c[]==now)^(tree[gfa].c[]==fa))rotate(now,root);
else rotate(fa,root);
rotate(now,root);
}
}
int find(int now,int k){
if(tree[now].change||tree[now].rev)pushdown(now);
int l=tree[now].c[];
if(k<=tree[l].size)return find(l,k);
else if(k==tree[l].size+)return now;
else return find(tree[now].c[],k-tree[l].size-);
}
void ins(int pos,int tot){
// int now=find(root,pos+1);
for(int i=;i<=tot;i++)scanf("%d",&a[i]);
for(int i=;i<=tot;i++)
if(!q.empty())id[i]=q.front(),q.pop();
else id[i]=++cnt;
int troot=id[(tot+)>>];
build(,tot,);
int x=find(root,pos+),y=find(root,pos+);
splay(x,root);splay(y,tree[x].c[]);
tree[y].c[]=troot;tree[troot].fa=y;
update(y);update(x);
// printf(" !%d\n",root);
}
void recover(int &now){
tree[now].fa=;
if(tree[now].c[])recover(tree[now].c[]);
if(tree[now].c[])recover(tree[now].c[]);
q.push(now);
tree[now].change=tree[now].rev=;
now=;
}
void del(int pos,int tot){
// int now=find(root,pos+1);
int x=find(root,pos),y=find(root,pos+tot+);
splay(x,root);splay(y,tree[x].c[]);
// int z=tree[y].c[0];tree[y].c[0]=0;
recover(tree[y].c[]);
update(y);update(x);//要更新祖先TAT
}
void bilibili(int pos,int tot,int change,int rev,int val){//处理修改&&翻转
int x=find(root,pos),y=find(root,pos+tot+);
splay(x,root);splay(y,tree[x].c[]);
// printf(" ! %d %d %d %d\n",tree[y].c[0],change,rev,val);
deal(tree[y].c[],change,rev,val);
update(y);update(x);//也要更新祖先TAT
// printf("! %d %d\n",y,x);
}
void getsum(int pos,int tot){
// int now=find(root,pos+1);
int x=find(root,pos),y=find(root,pos+tot+);
splay(x,root);splay(y,tree[x].c[]);
int z=tree[y].c[];
printf("%d\n",tree[z].sum);
}
int main(){
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)scanf("%d",&a[i+]);
a[]=a[n+]=-inf;
for(i=;i<=n+;i++)id[i]=i;
tree[].mx=-inf;
root=(n++)>>;cnt=n+;
build(,n+,);
// for(i=1;i<=cnt;i++)printf(" %d %d %d %d %d %d\n",i,tree[i].c[0],tree[i].c[1],tree[i].mx,tree[i].lmx,tree[i].rmx);
for(i=;i<=m;i++){
scanf("%s",iid);
if(iid[]=='S')scanf("%d%d",&x,&tot),ins(x,tot);
else if(iid[]=='L')scanf("%d%d",&x,&tot),del(x,tot);
else if(iid[]=='K')scanf("%d%d%d",&x,&tot,&c),bilibili(x,tot,,,c);
else if(iid[]=='V')scanf("%d%d",&x,&tot),bilibili(x,tot,,,);
else if(iid[]=='T')scanf("%d%d",&x,&tot),getsum(x,tot);
else if(iid[]=='X')printf("%d\n",tree[root].mx);
//if(i==4)
// for(int i=1;i<=cnt;i++)printf(" %d %d %d %d %d %d %d %d\n",i,tree[i].c[0],tree[i].c[1],tree[i].mx,tree[i].lmx,tree[i].rmx,tree[i].change,tree[i].rev);
// return 233;
}
return ;
}

//连续几天写到的题目都没有数据范围是什么鬼。。。

//至于读入的时候少打一个%d这种错显然只有傻叉才会犯的啊TAT

//变量名太长的悲剧。。。把几个过程缩成一个结果代码量还是别人的两倍T_T

感觉自己还不会splay。。。果然是太弱了。。也许过一阵子再来写这题效果会好点= =

2015.8.1:4h

2015.8.6:2h : 注意删点的时候那些新建节点时没有初始化的信息都要初始化,

2016.1.6:4h+。。TAT。。太久没玩懒标记结果卡了一晚上+一节电脑课。。。要好好想一下什么时候更新本节点的信息。。

[bzoj1500 维修数列](NOI2005) (splay)的更多相关文章

  1. BZOJ 1500/Luogu 2042 - 维修数列 - [NOI2005][Splay]

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1500 题目链接:https://www.luogu.org/problemnew/sho ...

  2. 【BZOJ1500】【NOI2005】维修数列(Splay)

    [BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...

  3. [bzoj1269]文本编辑器editor [bzoj1500]维修数列

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2540 Solved: 923 [Submit ...

  4. 【BZOJ1500】维修数列(splay)

    题意: 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的 ...

  5. 【BZOJ】1500: [NOI2005]维修数列(splay+变态题)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1500 模板不打熟你确定考场上调试得出来? 首先有非常多的坑点...我遇到的第一个就是,如何pushu ...

  6. NOI2005维修数列(splay)

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

  7. BZOJ1500 维修数列

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1500 [前言] 据说没打这题就相当于没打过Splay,这题简直就是让你内心崩溃的... 这 ...

  8. BZOJ 1500 维修数列【Splay】

    注意:1,内存限制,所以需要回收删除的点 2,当前节点的左连续区间和最大值=max(左子树的左连续区间和最大值,左子树的总和+当节点的值+max(右子树的左连续区间和最大值,0)):右连续区间和最大值 ...

  9. p2042 维修数列(SPLAY)

    终于yy过去了 撒花 调了一天半,出了无数锅 以下是出锅列表 rotate的时候要判断父亲节点的父亲节点是否存在 rotate的时候记得修改节点的父亲信息 pushdown的时候注意特判有无左右子树 ...

随机推荐

  1. Mac和Xcode常用的快捷键

    Mac电脑一般都不怎么用鼠标,因此除了触摸屏的各种双指.三指甚至四指的操作之外,快捷键的使用可以带来非常大的便利,本文则主要收集整理了自己在Mac常规和Xcode开发过程中常用的一些快捷键. 一.Ma ...

  2. 496. Next Greater Element I

    You are given two arrays(without duplicates)nums1andnums2wherenums1's elements are subset ofnums2. F ...

  3. 某次送温暖考试的 c题

    题目大意: 给定n个点的无根树,树上每个点都有一个非负的点权. 树上的路径的价值定义为树上路径的点权和-树上路径的点权最大值; 现在给定一个参数P询问有多少条路径的价值是P的倍数(注意单点也算路径,路 ...

  4. OpenStack运维(二):OpenStack计算节点的故障和维护

    1.计划中的维护 举例:需要升级某一个计算节点的硬件配置,需要将计算节点上的虚拟机迁移后在对其进行操作,分为两种情况. 1.1 云系统使用了共享存储 a. 获取虚拟机列表:nova list --ho ...

  5. 《重新定义公司 - Google 是如何运营的》重点摘录

      赋能:创意时代的组织原则 未来企业的成功之道,是聚集一批聪明的创意精英,营造合适的氛围和支持环境,充分发挥他们的创造力,快速感知用户需求,愉快地创造响应的产品和服务.未来组织的最重要功能,那就是赋 ...

  6. Mysql 索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  7. Python的类与类型

    1.经典类与新式类 在了解Python的类与类型前,需要对Python的经典类(classic classes)与新式类(new-style classes)有个简单的概念. 在Python 2.x及 ...

  8. 【转】彻底理解js中this的指向,不必硬背。

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  9. ASP.NET MVC 解决区域和全局控制器同名的问题

    话不多少 直接上代码 通常我们以为上边的是解决控制同名问题,是解决了一点,但是又出了以下问题,默认请求的不是项目默认的控制器而是该区域的控制器,在我之前开发的项目中,默认指向的是区域下的home控制器 ...

  10. MAC OS 如何安装命令行工具:Command Line Tools

    打开终端输入:xcode-select --install 回车 安装好了测试结果:gcc -v 显示如下: xcode-select: note: install requested for com ...