正题

题目链接:https://www.luogu.com.cn/problem/P2710


题目大意

nnn个数,mmm次操作要求支持

  1. 插入若干个数
  2. 删除某个位置开始的连续若干个数
  3. 翻转一个区间
  4. 修改一个区间为ttt
  5. 求区间和
  6. 输出一个位置的值
  7. 询问一个区间的最大子段和

解题思路

用SplaySplaySplay维护,记录lmaxlmaxlmax和rmaxrmaxrmax然后合并。要注意如果一个区间全是负数不能选空。

时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#define max3(x,y,z) max(max((x),(y)),(z))
using namespace std;
const int N=5e5+10,inf=2147483647/3;
int n,m,tot,root,t[N][2],fa[N],r[N],lazy[N],val[N];
int lmax[N],rmax[N],sum[N],ans[N],siz[N];
void PushUp(int x){lmax[x]=max(lmax[t[x][0]],sum[t[x][0]]+val[x]+lmax[t[x][1]]);rmax[x]=max(rmax[t[x][1]],sum[t[x][1]]+val[x]+rmax[t[x][0]]);ans[x]=max3(ans[t[x][0]],ans[t[x][1]],rmax[t[x][0]]+val[x]+lmax[t[x][1]]);sum[x]=sum[t[x][0]]+sum[t[x][1]]+val[x];siz[x]=siz[t[x][0]]+siz[t[x][1]]+1;return;
}
void Change(int x,int z){if(!siz[x])siz[x]=1;val[x]=z;sum[x]=z*siz[x];if(z>0)lmax[x]=rmax[x]=ans[x]=sum[x];else lmax[x]=rmax[x]=0,ans[x]=z;return;
}
void rev(int x){swap(t[x][0],t[x][1]);swap(lmax[x],rmax[x]);r[x]^=1;return;
}
void PushDown(int x){if(lazy[x]!=-inf){if(t[x][0])Change(t[x][0],lazy[x]),lazy[t[x][0]]=lazy[x];if(t[x][1])Change(t[x][1],lazy[x]),lazy[t[x][1]]=lazy[x];lazy[x]=-inf;}if(r[x]){rev(t[x][0]);rev(t[x][1]);r[x]=0;}PushUp(x);return;
}
void DownData(int x){if(!x)return;DownData(fa[x]);PushDown(x);return;
}
bool Direct(int x)
{return t[fa[x]][1]==x;}
void Connect(int x,int y,int dir)
{t[x][dir]=y;fa[y]=x;return;}
void Rotate(int x){int y=fa[x],z=fa[fa[x]];int xs=Direct(x),ys=Direct(y);Connect(y,t[x][xs^1],xs);Connect(x,y,xs^1);Connect(z,x,ys);PushUp(y);PushUp(x);return;
}
void Splay(int x,int f){DownData(x);while(fa[x]!=f){int up=fa[x];if(fa[up]==f)Rotate(x);else if(Direct(x)==Direct(up))Rotate(up),Rotate(x);else Rotate(x),Rotate(x);}return;
}
int Find(int x,int k){PushDown(x);if(siz[t[x][0]]>=k)return Find(t[x][0],k);if(siz[t[x][0]]+1==k)return x;return Find(t[x][1],k-siz[t[x][0]]-1);
}
int Split(int l,int r){int x=Find(root,l),y=Find(root,r+2);Splay(x,0);Splay(y,x);root=x;return t[y][0];
}
void write(int x){if(!x)return;write(t[x][0]);printf("%d ",val[x]);write(t[x][1]);
}
int main()
{scanf("%d%d",&n,&m);ans[0]=-inf;for(int i=0;i<N;i++)lazy[i]=-inf;siz[1]=1;Change(1,-inf);for(int i=2;i<=n+1;i++){scanf("%d",&val[i]);Change(i,val[i]);t[i][0]=i-1;fa[i-1]=i;PushUp(i); }Change(n+2,-inf);t[n+2][0]=n+1;fa[n+1]=n+2;PushUp(n+2);root=tot=n+2;while(m--){char op[15];scanf("%s",op);if(op[0]=='I'){int x;scanf("%d%d",&x,&n);int l=Find(root,x+1),r=Find(root,x+2);Splay(l,0);Splay(r,l);int last=++tot;scanf("%d",&x);t[r][0]=tot;fa[tot]=r;Change(tot,x);for(int i=2;i<=n;i++){scanf("%d",&x);Change(++tot,x);t[tot-1][1]=tot;fa[tot]=tot-1;}for(int i=tot;i>=last;i--)PushUp(i);Splay(last,0);root=last;}else if(op[0]=='D'){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);t[fa[x]][0]=0;PushUp(fa[x]);PushUp(fa[fa[x]]);}else if(op[0]=='R'){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);rev(x);PushUp(fa[x]);PushUp(fa[fa[x]]);}else if(op[0]=='M'&&op[2]=='K'){int x,w;scanf("%d%d%d",&x,&n,&w);x=Split(x,x+n-1);Change(x,w);lazy[x]=w;PushUp(fa[x]);PushUp(fa[fa[x]]);}else if(op[0]=='G'&&strlen(op)==7){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);printf("%d\n",sum[x]); }else if(op[0]=='G'){int x;scanf("%d",&x);x=Split(x,x);printf("%d\n",val[x]);}else if(op[0]=='M'){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);printf("%d\n",ans[x]);}
//      write(root);putchar('\n');}
}

P2710-数列【Splay】相关推荐

  1. BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay)

    BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay) 手动博客搬家: 本文发表于20180825 00:34:49, 原地址https://blog.csdn.ne ...

  2. [BZOJ1500][NOI2005]维修数列(splay)

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 16266  Solved: 5410 [Submit][Sta ...

  3. 【BZOJ1500】[NOI2005]维修数列 Splay

    [BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目. 第2 ...

  4. BZOJ1500 [NOI2005]维修数列(Splay tree)

    [Submit][Status][Discuss] Description 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线' _ '表示实际输入文件中的空格 Inp ...

  5. 1500: [NOI2005]维修数列 (Splay)

    1W1A(inf开太大) #include<algorithm> #include<iostream> #include<cstring> #include< ...

  6. OI每周刷题记录——lrllrl

    看这标题就知道我是模仿的hzwer大佬,远程%%% 大佬的OI经历让蒟蒻我深受感触,为了晚一些AFO本蒟蒻也得加油了 从高二上期第一周开始计数,每个星期天更一次,一直更到我AFO 如果这是我此生最后一 ...

  7. 数据结构(Splay平衡树):COGS 339. [NOI2005] 维护数列

    339. [NOI2005] 维护数列 时间限制:3 s   内存限制:256 MB [问题描述] 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线' _ '表示实际 ...

  8. [NOI2005]维护数列 恶心到毁天灭地的splay

    传送门 debug到死2333. 虽然说是splay维护序列模板,作为蒟蒻的我还是GG %%%考场A的dalao Orz  Orz. 其实不开long long也行,inf开成0x3f3f3f3f也可 ...

  9. [bzoj1500 维修数列](NOI2005) (splay)

    真的是太弱了TAT...光是把代码码出来就花了3h..还调了快1h才弄完T_T 号称考你会不会splay(当然通过条件是1h内AC..吓傻)... 黄学长的题解:http://hzwer.com/28 ...

  10. 【BZOJ1500】【codevs1758】维修数列,简析Splay的综合操作

    Time:2016.05.12 Author:xiaoyimi 转载注明出处谢谢 传送门1 传送门2 思路: 我的天啊! Splay大板子! 调了好久啊! 这里的Splay没有判断的key值,换一种说 ...

最新文章

  1. 新年来临,给大家送上机器学习,人工智能相关书籍,这可能是中奖率最高的一次送书活动...
  2. html怎么自动设为底部,让底部永远在页面最底部显示的css方法
  3. HTML标签类型及特点
  4. KETTLE调度第三篇:Windows下调度Dos脚本编写和遇到的一些问题解决
  5. 未来几十年替代手机的是什么产品?
  6. 了解SQL Server中的GUID数据类型
  7. OpenCV-绘制箭头cv::arrowedLine
  8. 5. CSS 类选择器
  9. 线性回归相关系数c语言,线性回归中的相关系数;
  10. 玩转树莓派——游戏主机模拟器
  11. 搜索优化之四叉树算法(三)
  12. A. 旅馆顾客统计(静态成员)
  13. 分享10个可免费使用的网站CDN加速服务
  14. 统计数据收集方式与收集方法
  15. Xcode8 最快最方便的安装插件方案
  16. uni-app中view和text组件和动画的使用
  17. OpenCV技巧 | 常用格式图片保存为透明背景图片(附Python源码)-教你轻松制作Logo
  18. 【算法刷题日记之本手篇】井字棋与密码强度等级
  19. 《生物信息学:导论与方法》----变异的功能预测----听课笔记(十一)
  20. 解决TP-LINK TL-WR740N 联网问题

热门文章

  1. python第k序列元素查找_Python寻找第k小的元素
  2. php maximum,解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示...
  3. mysql修改字段的顺序_Mysql中如何修改字段的排列顺序?
  4. 谁今天收到鸿蒙系统推送,鸿蒙系统正式推送,只有部分高端机才能收到
  5. ie插件获取dom_读书笔记《DOM编程艺术》DOM
  6. html点击图片弹出大图特效代码,Jquery 点击图片在弹出层显示大图
  7. w7下如何安装linux双系统,ubuntu安装教程(下): 教你装win7+Ubuntu双系统
  8. 后端学习 - 设计模式与设计原则
  9. C++与C语言中有关数组中元素排序
  10. [MyBatisPlus]常用注解_@TableName_@TableId_@TableField_@TableLogic通过全局配置配置主键生成策略