当前位置: 首页 > 编程日记 > 正文

[NOI2005]维护数列

输入格式

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

输出格式

对于输入数据中的 GET-SUM 和 MAX-SUM 操作,向输出文件依次打印结 果,每个答案(数字)占一行。

你可以认为在任何时刻,数列中至少有 1 个数。

输入数据一定是正确的,即指定位置的数在数列中一定存在。

100%的数据中,任何时刻数列中最多含有 500 000 个数。

100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。

100%的数据中,M ≤20 000,插入的数字总数不超过 4 000 000 。

题解

序列翻转基本操作

区间最大子段和

有了上面的铺垫,其实这些操作都可以解决了。

以下的根不做特殊说明都指区间代表子树的根。

只是有点小细节需要注意:

插入时要先把插入序列建splay,不然一个一个插入会超时。建splay时需要特判叶子节点维护一些信息,对于lmax和rmax需要将val和0取max,因为在父亲节点更新lmax是可能为左区间+父亲节点本身,如果右区间lmax直接取val,就可能取不到这种情况,或许比较三种情况可以解决这个问题,但是很麻烦不是吗。

删除的时候,把这段区间提取出来删除即可。不过因为空间原因需要回收节点编号,所以需要遍历这棵子树回收,用队列装编号。最多插入4e6个数,所以最多遍历4e6个点。

区间覆盖的时候,提取区间后,在根打上覆盖标记,维护节点信息:注意如果val是负数最大子段和赋成val。

翻转提取区间,在根打上翻转标记,将lmax和rmax交换

求和提取区间输出根的sum即可。

这道题的最大子段和是整个序列的,其实降低了一点难度,直接输出整颗splay的根的最大子段和即可。

下传在find里面。

建初始序列时要在收尾插入两个最小值,因为最大值在求最大子段和会有影响。

还有对于0号节点的最大子段和赋最小值,因为一些没有儿子的点更新信息会用到。

#include<bits/stdc++.h>
using namespace std;#define ll long long
const ll oo=1000000;
const int maxn=500005;
int n,m;
ll a[maxn],num,id[maxn],root;
queue<int> q;
struct Splay{int s[2],fa,size,tag,cover;//tag:当前节点是否需要交换儿子
  ll val,sum,dat,lmax,rmax;
}tr[maxn];template<class T>inline void read(T &x){x=0;int f=0;char ch=getchar();while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}x= f ? -x : x ;
}ll max(ll x,ll y){return x>y ? x : y ;}void update(Splay &ret,Splay lx,Splay ry){ret.size=lx.size+ry.size+1;ret.sum=lx.sum+ry.sum+ret.val;ret.lmax=max(lx.lmax,lx.sum+ret.val+ry.lmax);ret.rmax=max(ry.rmax,ry.sum+ret.val+lx.rmax);ret.dat=max(max(lx.dat,ry.dat),lx.rmax+ret.val+ry.lmax);//给0赋值防止了出事//printf("-%d-",ret.val);
}void update(int x){update(tr[x],tr[tr[x].s[0]],tr[tr[x].s[1]]);
}int build(int l,int r,int f){//printf("%d %d\n",l,r);if(l>r) return 0;int mid=(l+r)>>1,now=id[mid];tr[now].fa=f;tr[now].val=a[mid];tr[now].cover=oo;if(l==r){tr[now].size=1;tr[now].sum=tr[now].val;tr[now].lmax=tr[now].rmax=max(0,tr[now].val);tr[now].dat=tr[now].val;//记得赋值return now;}tr[now].s[0]=build(l,mid-1,now);tr[now].s[1]=build(mid+1,r,now);update(now);return now;
}void put_cover(int x,ll val){if(!x) return ;tr[x].val=tr[x].cover=val;tr[x].sum=val*tr[x].size;tr[x].lmax=tr[x].rmax= val>=0 ? tr[x].sum : 0;tr[x].dat= val>=0 ? tr[x].sum : val;//必须选取至少一个元素
}void put_tag(int x){if(!x) return ;tr[x].tag^=1;swap(tr[x].s[0],tr[x].s[1]);swap(tr[x].lmax,tr[x].rmax);
}void push_down(int x){if(tr[x].cover!=oo){put_cover(tr[x].s[0],tr[x].cover);put_cover(tr[x].s[1],tr[x].cover);tr[x].cover=oo;}if(tr[x].tag){put_tag(tr[x].s[0]);put_tag(tr[x].s[1]);tr[x].tag=0;}
}void debug(int x){push_down(x);if(tr[x].s[0]) debug(tr[x].s[0]);printf("%lld ",tr[x].val);if(tr[x].s[1]) debug(tr[x].s[1]);
}int find(int k){int now=root;while(1){//printf("%d %d\n",k,now);
    push_down(now);if(tr[tr[now].s[0]].size>=k) {now=tr[now].s[0];continue;}k-=tr[tr[now].s[0]].size;if(k==1) return now;k--;now=tr[now].s[1];}
}int get(int x){return tr[tr[x].fa].s[1]==x;
}void connect(int x,int y,int d){tr[y].s[d]=x;tr[x].fa=y;
}void rotate(int x){int f=tr[x].fa,ff=tr[f].fa;int d1=get(x),d2=get(f);int cs=tr[x].s[d1^1];connect(x,ff,d2);connect(f,x,d1^1);connect(cs,f,d1);update(f);update(x);
}void splay(int x,int go){if(go==root) root=x;go=tr[go].fa;while(tr[x].fa!=go){int f=tr[x].fa;if(tr[f].fa==go) rotate(x);else if(get(x)==get(f)) {rotate(f);rotate(x);}else {rotate(x);rotate(x);}}
}void insert(){int pos,tot;read(pos);read(tot);n+=tot;for(int i=1;i<=tot;i++){read(a[i]);if(!q.empty()) id[i]=q.front(),q.pop();else id[i]=++num;}int nowroot=build(1,tot,0);int x=find(pos+1),y=find(pos+2);splay(x,root);splay(y,tr[x].s[1]);tr[nowroot].fa=y;tr[y].s[0]=nowroot;update(y);update(x);
}void clean(int x){tr[x]=(Splay){{0,0},0,0,0,oo,0,0,0,0,0};
}void recycle(int x){if(tr[x].s[0]) recycle(tr[x].s[0]);if(tr[x].s[1]) recycle(tr[x].s[1]);clean(x);q.push(x);
}void dele(){int pos,tot;read(pos);read(tot);n-=tot;int x=find(pos),y=find(pos+tot+1);splay(x,root);splay(y,tr[x].s[1]);recycle(tr[y].s[0]);tr[y].s[0]=0;update(y);update(x);
}void modify(){int pos,tot;ll val;read(pos);read(tot);read(val);int x=find(pos),y=find(pos+tot+1);splay(x,root);splay(y,tr[x].s[1]);put_cover(tr[y].s[0],val);update(y);update(x);
}void reverse(){int pos,tot;read(pos);read(tot);int x=find(pos),y=find(pos+tot+1);splay(x,root);splay(y,tr[x].s[1]);put_tag(tr[y].s[0]);update(y);update(x);
}ll querysum(){int pos,tot;read(pos);read(tot);int x=find(pos),y=find(pos+tot+1);splay(x,root);splay(y,tr[x].s[1]);//printf("%d %d\n",x,y);//printf("%d\n",tr[tr[y].s[0]].size);//putchar(10);//debug(tr[y].s[0]);//putchar(10);return tr[tr[y].s[0]].sum;
}ll querydat(){int x=find(1),y=find(n);splay(x,root);splay(y,tr[x].s[1]);return tr[tr[y].s[0]].dat;
}int main(){read(n);read(m);tr[0].dat=a[1]=a[n+2]=-oo;//给零赋值,不然建树会出锅for(int i=1;i<=n;i++) read(a[i+1]);for(int i=1;i<=n+2;i++) id[i]=++num;n=n+2;root=build(1,n,0);for(int i=1;i<=m;i++){char opt[15];scanf("%s",opt);if(opt[2]=='S') insert();else if(opt[2]=='L') dele();else if(opt[2]=='K') modify();else if(opt[2]=='V') reverse();else if(opt[2]=='T') printf("%lld\n",querysum());else printf("%lld\n",tr[root].dat);//putchar(10);//debug(root);//putchar(10);
  }
}
View Code

转载于:https://www.cnblogs.com/sto324/p/11297521.html

相关文章:

java 常用正则表达式

匹配中文字符的正则表达式&#xff1a; [\u4e00-\u9fa5]评注&#xff1a;匹配中文还真是个头疼的事&#xff0c;有了这个表达式就好办了匹配双字节字符(包括汉字在内)&#xff1a;[^\x00-\xff]评注&#xff1a;可以用来计算字符串的长度&#xff08;一个双字节字符长度计2&…

考研总结以及假期规划

从标题不难看出&#xff0c;这是自我总结的水文一篇 备考总结 持续了将近一年的备考时间结束了&#xff0c;漫无目的地玩了几天的手机之后&#xff0c;感觉需要做点什么来充实一下自己了。&#xff08;写下这句话之后又回去玩手机了&#xff0c;直到昨天山东泰山拿了双冠王受到…

JAVA Functions in XI(转)

JAVA Functions in XI 1. Split Function 按字符分割成字符串数组 String [ ] StrArray LGORT.split(",") //-- pass LGORT to this UDF int len1 LGORT.length; for ( i0;i<len1;i){ result.addValue(StrArray[i]); } 2. Global Containers…

2018.5.29 Oracle连接到空闲例程

解决方法如下&#xff1a; 1、通过cmd命令窗启动Oracle&#xff1a;(最好是以管理员身份启动) C:\Users\Administrator>sqlplus /nolog SQL>conn /as sysdba 或者这种 conncet sys/123456orcl as sysdba //sys是用户名 123456是密码 。 后面的是数据库名字 SQL>s…

关于css中float的一切

原文&#xff1a;http://css-tricks.com/all-about-floats/ 这篇文章说的简单易懂 float是CSS中关于定位的属性。 float有4个值&#xff1a;none, left, right, inherit (继承父元素的float属性值&#xff09; float的姐妹属性&#xff1a;clear clear有4个值&#xff1a;both…

【光纤通信】关于RFA(喇曼光纤放大器)

近日在准备考研复试&#xff0c;在学习光纤通信的时候对书中关于RFA的解释不是很理解&#xff0c;经过查阅文献后将自己此刻的理解记录一下。 喇曼散射 解释一&#xff1a; “入射泵浦光子通过光纤的非线性散射转移部分能量&#xff0c;产生低频斯托克斯光子&#xff0c;而剩…

艾伟_转载:学习 ASP.NET MVC (第五回)理论篇

本系列文章导航学习 ASP.NET MVC &#xff08;第一回&#xff09;理论篇学习 ASP.NET MVC &#xff08;第二回&#xff09;实战篇学习 ASP.NET MVC &#xff08;第三回&#xff09;实战篇学习 ASP.NET MVC &#xff08;第四回&#xff09;实战篇学习 ASP.NET MVC &#xff08;第…

Jmeter(二十九)_dotnet搭建本地接口服务

这里使用的服务名为Bookshelf&#xff0c;在github上&#xff0c;自行下载。要运行此服务&#xff0c;需要.Net Core SDK 2.1或更高版本。如果尚未安装&#xff0c;从.Net Core官方网站下载并安装。 在本地克隆项目后&#xff0c;在命令行工具中打开项目文件夹并运行“dotnet r…

【eclipse】eclipse使用常见问题(持续更新)

创建maven工程中没有src/main/java及src/main/test文件夹 解决方法&#xff1a; 第一步 第二步 第三步 【eclipse】快速调整eclipse背景和格式的方法 第一步 第二步 第三步 &#xff1a;选择相应的格式 效果如图 eclipse 中使包名按层级显示的方法 使用eclipse在没网时编写配置…

Prometheus+Granfana

二、虚机&#xff08;服务器&#xff09;方式prometheus在虚机&#xff08;服务器&#xff09;中安装运行。 命令行启动在安装完成以后&#xff0c;可以直接在命令行启动。启动方式通常是&#xff1a; ./prometheus --config.fileprometheus.yml & 或者nohup /opt/promethe…

【原创】Cookie应用(二)

Cookie的作用很大&#xff0c;在很多技术方案中都有应用。它也是Forms身份认证模式所使用的一门技术点。 今天我就说一说它在Forms身份认证模式中都起到什么作用。 &#xff08;一&#xff09;理论知识 ASP.NET 使用身份验证提供程序实现附加的身份验证方案&#xff0c;这些身份…

艾伟_转载:探索.Net中的委托

废话 我本来以为委托很简单&#xff0c;本来只想简简单单的说说委托背后的东西&#xff0c;委托的使用方法。原本只想解释一下那句&#xff1a;委托是面向对象的、类型安全的函数指针。可没想到最后惹出一堆的事情来&#xff0c;越惹越多&#xff0c;罪过&#xff0c;罪过。本文…

OO第三阶段总结

1、 规格化设计的发展 我认为规格化设计的需求主要来源于在软件与互联网行业飞速发展下&#xff0c;工程随着代码量的增长&#xff0c;往往会显得异常的臃肿&#xff0c;难以阅读。这为多人合作的工程创造了巨大的不便。而在这样的背景下&#xff0c;大家都认为代码风格的统一和…

ubuntu18.04 -- 创建第一个Django项目

step1&#xff1a; 安装虚拟环境&#xff1a; sudo pip3 install virtualenv # 安装虚拟环境sudo pip3 install virtualenvwrapper # 安装虚拟环境扩展包# 编辑家目录下的 .bashrc 文件&#xff0c;在最下面添加下面三行代码 export WORKON_HOME$HOME/.virtualenvs #指定…

单链表逆序生成及逆置的完整实现

单链表逆序生成及逆置的完整实现 本例中单链表数据类型定义成int型&#xff0c;可更改 头文件1(1.h) 宏定义及Status类型定义 头文件2(2.h) 单链表基本操作函数与逆置函数 include"1.h" using namespace std;typedef int ElemType; typedef struct LNode{ElemTyp…

html frameset

两个frame <frameset cols"25%,75%"> <frame name "frame1" src"frame_a.php" /><frame name "frame2" /></frameset> 如果在PHP中要实现在frame刷新 frame echo "<meta http-equiv\"Refre…

黄聪:Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)...

去空格及特殊符号 s.strip().lstrip().rstrip(,) 复制字符串 #strcpy(sStr1,sStr2) sStr1 strcpy sStr2 sStr1 sStr1 strcpy2 print sStr2 连接字符串 #strcat(sStr1,sStr2) sStr1 strcat sStr2 append sStr1 sStr2 print sStr1 查找字符 #strchr(sStr1,sStr2) # < 0 …

Java图形化界面设计——容器(JFrame)

Java图形化界面设计——容器&#xff08;JFrame&#xff09; 程序是为了方便用户使用的&#xff0c;因此实现图形化界面的程序编写是所有编程语言发展的必然趋势&#xff0c;在命令提示符下运行的程序可以让我们了解java程序的基本知识体系结构&#xff0c;现在就进入java图形化…

分库分表之后,主键的处理方法

面试题 分库分表之后&#xff0c;id 主键如何处理&#xff1f; 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题&#xff0c;就是 id 咋生成&#xff1f;因为要是分成多个表之后&#xff0c;每个表都是从 1 开始累加&#xff0c;那肯定不对啊&#xff0c;需要一个全…

用队列实现形如a+b@b+a#的中心对称字符的检验

用队列实现形如abba#的中心对称字符的检验 我用网上提供的一种思想&#xff0c;用循环队列实现了这个操作&#xff0c;具体代码如下。 /*函数名match,严格来说它并不是Status型*/ Status match(char *a){SqQueue q; //定义循环队列q ch…

如何使用JPA注解标注多对多的关系

假设应用场景如下&#xff1a;Teacher与Student是多对多的关系&#xff0c;其中&#xff0c;Teacher类对应teacher表如下&#xff1a; CREATE TABLE teacher (id bigint(20) NOT NULL AUTO_INCREMENT,name varchar(50) DEFAULT NULL,PRIMARY KEY (id)) ENGINEInnoDB AUTO_INCRE…

艾伟也谈项目管理,敏捷教练的工具箱

学习并不是简简单单的阅读和浏览&#xff0c;而是一个积累的过程&#xff0c;一个通过持续的学习&#xff0c;对自己的知识体系不断丰富、索引的过程。接下来我会从四个方面入手分享我的经验。 高质量的信息源和高效的学习 Google是一个很好的工具&#xff0c;通过它&#xff…

7.Odoo产品分析 (二) – 商业板块(3) –CRM(1)

查看Odoo产品分析系列—-目录 CMR&#xff1a;Customer Relationship Management。企业为提高核心竞争力&#xff0c;利用相应的信息技术以及互联网技术协调企业与顾客间在销售、营销和服务上的交互&#xff0c;从而提升其管理方式&#xff0c;向客户提供创新式的个性化的客户交…

用栈实现形如a+bb+a@的中心对称字符的检验

用栈实现形如ab&ba的中心对称字符的检验 将&前字符依次入栈与前字符进行比较即可&#xff0c;下面是方法 Status match(char *a){ //match方法 SqStack s; char c; char *pa; InitStack(s); while(*p!&){ …

Typedef用法(转载)

在C的学习过程中&#xff0c;现在才发现&#xff0c;以前有那么多被忽略的重点&#xff1b;现在是慢慢拾起这些重点的时候&#xff0c;通过百度和博客&#xff0c;我感觉我学到了很多东西&#xff0c;自己只是在别人说的基础上&#xff0c;按照自己学习的过程在这里记录一下&am…

JavaScript基本知识

数组的排序 JavaScript可以实现多维数组,对象数组等排序,语法如下 arrayobj.sort(sortfunction) 参数 arrayObj 必选项。任意 Array 对象。 sortFunction 可选项。是用来确定元素顺序的函数的名称。如果这个参数被省略&#xff0c;那么元素将按照 ASCII 字符顺序进行升序排列…

七基于Fourinone实现MQ demo

2019独角兽企业重金招聘Python工程师标准>>> FourInOne也可以当成简单的mq来使用&#xff0c;该demo演示了队列和主题订阅两种模式的实现 一、队列 将domain视为mq队列&#xff0c;每个node为一个队列消息&#xff0c;检查domain的变化来获取队列消息。 Sender&…

Windows下安装XAMPP,Wordpress

配置XAMPP&#xff1a; 1、下载&#xff1a;https://www.apachefriends.org/zh_cn/download.html&#xff08;下载速度日了狗&#xff01;&#xff09; 2、安装XAMPP; 3、启动apache&#xff0c;MySQL&#xff1a; Apache启动错误&#xff1a; …

原生js实现复制

最后我的解决方案是&#xff0c;在页面中添加一个 div&#xff0c;手动写入内容innerHTML&#xff0c;然后把它隐藏掉 function copy(targetDom) {let range document.createRange();range.selectNode(hiddenErrcode);window.getSelection().removeAllRanges();window.getSele…

C#条件判断-根据条件判断要走的路-if结构

什么时候要用到if结构语句呢?如果有一个班的学生期末成绩不是很理想&#xff0c;原因是考题太难&#xff0c;教师希望根据学生平时的表现给不同学生加平时成绩分&#xff0c;条件如下&#xff1a; 如果平时每次都交作业&#xff0c;加20分&#xff1b;如果平时交了超过所有作业…