[NOI2005] 维修数列
1500: [NOI2005]维修数列
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 8397 Solved: 2530
Description

Input
输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。第2行包含N个数字,描述初始时的数列。以下M行,每行一条命令,格式参见问题描述中的表格。
Output
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。
Sample Input
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
10
1
10
HINT

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 500010 int n,m,num[N];
struct SplayTree
{
int sz[N],ch[N][],pre[N],que[N],sta[N];
int top1,top2,root; int sum[N],maxm[N],maxl[N],maxr[N],val[N];
bool ro[N],same[N]; inline void SameNode(int x,int c)
{
if(x==) return;
val[x]=c;
sum[x]=sz[x]*val[x];
maxm[x]=maxl[x]=maxr[x]=max(sum[x],val[x]);
same[x]=;
}
inline void ReverseNode(int x)
{
if(x==) return;
ch[x][]^=ch[x][]^=ch[x][]^=ch[x][];
maxl[x]^=maxr[x]^=maxl[x]^= maxr[x];
ro[x]^=;
}
inline void PushDown(int x)
{
if(x==) return;
if(ro[x])
{
ReverseNode(ch[x][]);
ReverseNode(ch[x][]);
ro[x]^=;
}
if(same[x])
{
SameNode(ch[x][],val[x]);
SameNode(ch[x][],val[x]);
same[x]=;
}
}
inline void PushUp(int x)
{
if(x==) return;
sz[x]=+sz[ch[x][]]+sz[ch[x][]];
sum[x]=val[x]+sum[ch[x][]]+sum[ch[x][]];
maxl[x]=max(maxl[ch[x][]],sum[ch[x][]]+val[x]+max(,maxl[ch[x][]]));
maxr[x]=max(maxr[ch[x][]],sum[ch[x][]]+val[x]+max(,maxr[ch[x][]]));
maxm[x]=max(max(maxl[ch[x][]],)+val[x]+max(maxr[ch[x][]],),max(maxm[ch[x][]],maxm[ch[x][]]));
}
inline void Rotate(int x,int c)
{
int y=pre[x];
PushDown(y);
PushDown(x);
ch[y][!c]=ch[x][c];
if(ch[x][c]) pre[ch[x][c]]=y;
pre[x]=pre[y];
if(pre[y]) ch[pre[y]][ch[pre[y]][]==y]=x;
ch[x][c]=y;
pre[y]=x;
PushUp(y);
if(y==root) root=x;
}
inline void Splay(int x,int f)
{
PushDown(x);
while(pre[x]!=f)
{
PushDown(pre[pre[x]]);
PushDown(pre[x]);
PushDown(x);
if(pre[pre[x]]==f) Rotate(x,ch[pre[x]][]==x);
else
{
int y=pre[x],z=pre[y];
int c=(ch[z][]==y);
if(ch[y][c]==x) Rotate(x,!c),Rotate(x,c);
else Rotate(y,c),Rotate(x,c);
}
}
PushUp(x);
if(f==) root=x;
}
inline void SplayKth(int k,int f)
{
int x=root;
k+=;
while()
{
PushDown(x);
if(k==sz[ch[x][]]+) break;
else if(k<=sz[ch[x][]]) x=ch[x][];
else k-=sz[ch[x][]]+,x=ch[x][];
}
Splay(x,f);
}
inline void Erase(int x)
{
int head=,rear=;
que[head]=x;
while(head<=rear)
{
sta[++top2]=que[head];
if(ch[que[head]][]) que[++rear]=ch[que[head]][];
if(ch[que[head]][]) que[++rear]=ch[que[head]][];
head++;
}
}
inline void NewNode(int &x,int c)
{
if(top2) x=sta[top2--];
else x=++top1;
ch[x][]=ch[x][]=pre[x]=;
sz[x]=;
ro[x]=same[x]=;
val[x]=sum[x]=maxm[x]=maxl[x]=maxr[x]=c;
}
inline void Build(int &x,int l,int r,int f)
{
if(l>r) return;
int m=(l+r)>>;
NewNode(x,num[m]);
Build(ch[x][],l,m-,x);
Build(ch[x][],m+,r,x);
pre[x]=f;
PushUp(x);
}
inline void Init(int n)
{
ch[][]=ch[][]=pre[]=sz[]=;
ro[]=same[]=;
maxr[]=maxl[]=maxm[]=-;
sum[]=;
root=top1=top2=;
for(int i=;i<=n;i++) scanf("%d",&num[i]);
Build(root,,n+,);
}
void GetSum()
{
int a,b;
scanf("%d%d",&a,&b);
SplayKth(a-,);
SplayKth(a+b,root);
printf("%d\n", sum[ch[ch[root][]][]]);
}
void MaxSum()
{
SplayKth(, );
SplayKth(sz[root]-,root);
printf("%d\n",maxm[ch[ch[root][]][]]);
}
void Insert()
{
int pos,tot;
scanf("%d%d",&pos,&tot);
for(int i=;i<=tot;i++) scanf("%d", &num[i]);
SplayKth(pos,);
SplayKth(pos+,root);
Build(ch[ch[root][]][],,tot,ch[root][]);
PushUp(ch[root][]);
PushUp(root);
}
void Delete()
{
int pos,tot;
scanf("%d%d",&pos,&tot);
SplayKth(pos-,);
SplayKth(pos+tot,root);
Erase(ch[ch[root][]][]);
ch[ch[root][]][]=;
PushUp(ch[root][]);
PushUp(root);
}
void MakeSame()
{
int pos,tot,c;
scanf("%d%d%d",&pos,&tot,&c);
SplayKth(pos-,);
SplayKth(pos+tot,root);
SameNode(ch[ch[root][]][],c);
}
void Reverse()
{
int pos,tot;
scanf("%d%d",&pos,&tot);
SplayKth(pos-,);
SplayKth(pos+tot,root);
ReverseNode(ch[ch[root][]][]);
}
}t;
int main()
{
char op[];
scanf("%d%d",&n,&m);
t.Init(n);
while(m--)
{
scanf("%s",&op);
if(op[]=='G') t.GetSum();
else if(op[]=='M' && op[]=='X') t.MaxSum();
else if(op[]=='I') t.Insert();
else if(op[]=='D') t.Delete();
else if(op[]=='M' && op[]=='K') t.MakeSame();
else if(op[]=='R') t.Reverse();
}
return ;
}
[NOI2005] 维修数列的更多相关文章
- bzoj 1500: [NOI2005]维修数列 splay
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 6556 Solved: 1963[Submit][Status ...
- [BZOJ1500][NOI2005]维修数列---解题报告
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- BZOJ_1500_[NOI2005]维修数列_splay
BZOJ_1500_[NOI2005]维修数列_splay 题意: 分析: 节点维护从左开始的最大连续子段和,从右开始的最大连续子段和,区间的最大连续子段和 插入:重新建一棵树,把pos旋到根,把po ...
- bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)
http://www.lydsy.com/JudgeOnline/problem.php?id=1500 1.覆盖标记用INF表示无覆盖标记,要求可能用0覆盖 2.代表空节点的0号节点和首尾的两个虚拟 ...
- [BZOJ1500][NOI2005]维修数列 解题报告 Splay
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- BZOJ 1500: [NOI2005]维修数列 (splay tree)
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 4229 Solved: 1283[Submit][Status ...
- 【BZOJ1500】[NOI2005]维修数列 Splay
[BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行 ...
- [bzoj1500][NOI2005]维修数列_非旋转Treap
维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...
- 【BZOJ】1500: [NOI2005]维修数列
[算法]splay [题解]数据结构 感谢Occult的模板>_<:HYSBZ 1500 维修数列 #include<cstdio> #include<cctype> ...
随机推荐
- GridView分页排序
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GridviewPage.asp ...
- 使用OpenXml操作Excel,以下方法用于在添加列时修改Cell的CellReference属性。
以下方法实现了递增Excel中单元格的CellReference的功能,只支持两位字母. public static string CellReferenceIncrement(string cell ...
- Eclipse编辑器基本设置
1.添加行号 在边缘处右键 2.改字体 字体的一般配置 3.去掉拼写错误检查 4.Java代码风格 代码格式化 Ctrl + Shift + F 之后点击右边的New按钮,新建一个风格. 点击OK 上 ...
- 微软职位内部推荐-Principal DEV Manager for Bing Client
微软近期Open的职位: Title: Principal DEV Manager for Bing ClientGroup: Search Technology Center Asia, BingW ...
- 轻仿QQ音乐之音频歌词播放、锁屏歌词-b
先上效果图 歌词播放界面 音乐播放界面 锁屏歌词界面 一. 项目概述 前面内容实在是太基础..只想看知识点的同学可以直接跳到第三部分的干货 项目播放的mp3文件及lrc文件均来自QQ音乐 本文主要主要 ...
- xx创新论坛返工友情项目总结
友情项目,顾名思义就不是我做的,只是处于友情帮别人改改别人的代码帮别人找找bug...之所以要强调这一点是因为里面的低级问题太多,实在是不好意思承认自己和这个项目有关系.. 整个过程还是挺辛苦的,毕竟 ...
- MVC EF异常-“序列化类型为 XX 的对象时检测到循环引用”
原因:在EF实体中,两个互为主外键关系的实体类的导航属性相互引用. 解决方法一:删除一个不需要的类的导航属性 方法二:使用DTO模型 方法三:直接返回需要的属性(不能包括相互引用的属性)
- PAT-乙级-1044. 火星数字(20)
1044. 火星数字(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 火星人是以13进制计数的: 地球人的 ...
- hdu 4665
转载一下 用的搜索 竟然过了 ............代码 ....... #include<stdio.h> #include<string.h> #include&l ...
- 1964-NP
描述 Problems in Computer Science are often classified as belonging to a certain class of problems (e. ...