【SPOJ GSS】数据结构题选做
SPOJ GSS1
题意:给一个序列以及一些询问,每个是问\([l,r]\)中最大连续子序列和是多少。
思路:这个问题是以下问题的基础。
我们考虑用线段树来解决这个问题。
首先我们来想想如果要求出最大连续子序列和需要什么信息。
对于\([l,m)\)和\([m,r)\)这两个区间,我们需要将它们合并成\([l,r)\)这个区间。
那么我们考虑分治地来解决这个问题。把问题分成三部分:
- \([l,m)\)中的最大子序列和
- \([m,r)\)中的最大子序列和
- 左端点在\([l,m)\)内,右端点在\([m,r)\)内的最大子序列和。
其中前两个部分可以递归处理,而第\(3\)个部分则需要记录\([l,m)\)的最大后缀和以及\([m,r)\)的最大前缀和,以便求出此部分的值。所以对每个节点维护\([l,r)\)的和、最大子序列和、最大前缀和、最大后缀和。
将值上推的时候这样做:
- 首先将\([l,r)\)的和设为\([l,m)\)的和加上\([m,r)\)的和。
- 然后考虑最大前缀和(最大后缀和与之对称,略):这个最大前缀和的结尾可能有两种情况:
- 在\([l,m)\)中,即\([l,m)\)的最大前缀和
- 在\([m,r)\)中,即\([l,m)\)的和加上\([m,r)\)的最大前缀和
- 然后最大子序列和就是\([l,m)\)的最大后缀和加上\([m,r)\)的最大前缀和。
然后就好辣。
SPOJ GSS 2
题意:给定一个序列,每次询问区间内最大去重子段和。
思路:这题比第一题就多了几个字,但是难度确是天上地下。。。
首先这个肯定是在线做不来的,那么考虑离线处理。
那么我们看如果我们将区间的右端点\(R\)右移一位之后会发生什么。
假设\(a_R\)最后一次出现是\(b_{a_R}\),那么我们考虑从\(1\)到\(R\)每一个点开始一直到\(R\)的这个子段的和的变化。
首先\(b_{A_R}\)及其前肯定不会有任何变化,那么只是\(b_{a_R}+1\)到\(R\)的区间内会加上\(a_R\)。
为了处理\(i\)到\(i..R\)的最大子段和,那么我们需要对于每一个点记录历史最大值。
所以考虑线段树。每一个节点\(i\)代表的区间是\([lb_i,rb_i)\),中点为\(md_i\),对\(i\)存储以下信息:
- \([lb_i,rb_i)\)的最大值和历史最大值
- \([lb_i,rb_i)\)的增加值和历史最大增加值
然后我的思路就到这里了。。。我怎么搞都搞不对下推操作。。。然后看了魏铭神仙的题解发现下推应该这么做:
以\([lb_i,rb_i)\)下推到\([lb_i,md_i)\)为例,下推到\([md_i,rb_i)\)同理。
首先我们考虑怎么用\([lb_i,rb_i)\)的历史最大增加值去改变\([lb_i,md_i)\)的历史最大值。
首先确定\([lb_i,rb_i)\)的历史最大增加值是相对于上一次下推而言的,并不是全局历史最大。
那么\([lb_i,md_i)\)的历史最大值就肯定需要和\([lb_i,md_i)\)现在的最大值\(+[lb_i,rb_i)\)的历史最大增加值取一个\(max\)。
下面考虑\([lb_i,md_i)\)的历史最大增加值和\([lb_i,rb_i)\)的历史最大增加值的关系。
首先我们知道现在\([lb_i,md_i)\)增加多少,并且这个值在"历史"的范围内是没有改变过的(要不然肯定下推了),所以我们应该将\([lb_i,md_i)\)的历史最大增加值和\([lb_i,rb_i)\)的历史最大增加值\(+[lb_i,md_i)\)的增加值取个\(max\)。
\([lb_i,md_i)\)的增加值和最大值和正常的线段树相同,略。
下面来想上推操作。这就比较简单了,只是将两个儿子的最大值推到当前的最大值上,当前的历史最大值和最大值再取一个\(max\)即可。
好难啊。。。
SPOJ GSS3
题意:给一个序列以及一些询问,每个是\(1)\)将\(x\)这一位上的数改成\(v\);\(2)\)问\([l,r]\)中最大连续子序列和是多少。
思路:这题比GSS1只是多了修改操作,而这只是单点修改,所以直接加上正常线段树的\(update\)操作即可。
SPOJ GSS4
题意:给一个序列,有以下几种询问:
- 将\([l,r]\)的所有数都改成它们的正平方根
- 求\([l,r]\)的和
思路:首先我们看求平方根的特性。
最大从\(10^{18}\)开始,到\(10^9\),\(31622\),\(177\),\(13\),\(3\),\(1\)。所以我们知道将每一个数一直取平方根能取的次数是常数级的,到\(1\)之后就会出现循环,那么我们只用维护一个\(set\)来存储所有的非\(1\)的数,每次询问的时候如下处理:
- 对于修改操作,我们只需要在\(set\)中找到所有的在\([l,r]\)这个区间中的数,把他们变成自己的平方根,在\(bit\)中区间修改一下即可。如果中间有某个数变成了\(1\),那么我们就将其从\(set\)中删去。
- 对于查询操作,只需要在\(bit\)中查询和即可。
所以这题这样一分析就一点都不难了。
SPOJ GSS5
题意:给一个序列以及一些询问,每个是问\(max\ \sum_{k=i}^ja_k(x_1\leq i\leq y_1,x_2\leq j\leq y_2,x_1\leq x_2,y_1\leq y_2)\)。
思路:我们将\(y_1\)和\(x_2\)的大小情况分两类考虑:
- \(y_1<x_2\)时,这两个区间没有任何交叉,所以答案肯定是\([x_1,y_1]\)的最大后缀和加上\([y_1+1,x_2-1]\)的和加上\([x_2,y_2]\)的最大前缀和。
- \(y_1\geq x_2\)时,这两个区间的交叉是\([x_2,y_1]\)这段,那么我们要分几种情况考虑:
- \(i\)在\([x_1,x_2-1]\)里,\(j\)在\([x_2,y_1]\)里:\([x_1,x_2-1]\)的最大后缀和加上\([x_2,y_1]\)的最大前缀和。
- \(i\)在\([x_1,x_2-1]\)里,\(j\)在\([y_1+1,y_2]\)里:\([x_1,x_2-1]\)的最大后缀和加上\([x_2,y_1]\)的和加上\([y_1+1,y_2]\)的最大前缀和。
- \(i\)在\([x_2,y_1]\)里,\(j\)在\([i,y_1]\)里:\([x_2,y_1]\)的最大连续子序列和。
- \(i\)在\([x_2,y_1]\)里,\(j\)在\([y_1+1,y_2]\)里:\([x_2,y_1]\)的最大后缀和加上\([y_1+1,y_2]\)的最大前缀和。
- 然后取\(max\)就好辣。
SPOJ GSS6
题意:给一个序列,有以下询问类型:
- \(I\ x\ v\):在第\(x-1\)位和第\(x\)位之间插入\(v\)
- \(D\ x\):删除第\(x\)位
- \(R\ x\ v\):把第\(x\)位替换成\(v\)
- \(Q\ x\ y\):求\(max_{x\leq i\leq j\leq y}\sum_{k=i}^ja_k\)。
思路:由于有插入删除我们不能用线段树了,那么就用\(FHQ\ Treap\)吧。
首先我们在\(treap\)的每个节点中存储的信息应该和GSS1中线段树的每个节点存储的信息差不多:
这个节点所代表的区间的最大前缀和、最大后缀和、最大连续子序列和、和,以及这个节点的值。
然后只需要实现\(pushup\)操作在\(split\)和\(merge\)的时候将节点两个儿子的信息推到上面去就可以了。
有个坑:它的数据中行末有空格!!!所以\(getchar\)并不怎么好使。。。
我第一开始竟然忘了\(pushup\)这个节点代表的区间的和。。。
所以其实这题比GSS7简单多了。。。
思路:按照魏铭的方法写的。他竟然用了\(Splay\)。。。写疯掉了,\(splay\)和\(rotate\)两个函数已经忘的差不多了,想了半天。。。然后其中如果要查询一个区间就把区间的右端点后一个和左端点分别splay到根和根的左节点,那么根的左节点的右子树就是需要查询的区间。比Treap不知道难搞了多少。。。
SPOJ GSS7
题意:给一棵树以及一些询问,每个是\(1)\)将\(a\rightarrow b\)的路径上每一个点都赋成\(c\);\(2)\)问\(a\rightarrow b\)的路径上每一个点组成的序列的最大连续子序列和。
思路:树链剖分都出来了。。。
先看第一个询问。
这个询问还是比较普通的。。。
套个树链剖分的模板做一下就行了,不过线段树中还要加上区间修改的操作。其实也蛮简单的:)
然后我们考虑第二个询问。
首先这个不可以套模板了。。。
最大连续子序列和不是个可以分段搞的东西。。。
然后放弃想了想发现我们可以\(O(log^2)\)地做!!!
首先我们按照正常步骤来把这条路径上所有的重链作为一个个区间,记为\(A_{1..m}\)。
然后我们根据(da)树链剖分(le)复杂度(ge)的证明(biao)发现\(m\)不会超过\(O(log\ n)\)。
所以开心地暴力。。。
枚举区间开头\(l\),区间结尾\(r\),那么就是\(\sum_{i=l+1}^{r-1}A_i\)的和加上\(A_l\)的最大后缀和加上\(A_r\)的最大前缀和。
还有一种情况就是答案就在\(A_i\)中,即\(A_i\)的最大连续子序列和。
搞死我了。。。写了\(5K\)。。。
思路:按照魏铭的方法写的。他在求答案的时候写得非常自然,用了线段树中写的\(pushup\)函数,将整个长链变成了一个节点,左右两个节点再合并一下变成一个。这样写的既比我的方便又自然。
【SPOJ GSS】数据结构题选做的更多相关文章
- Atcoder 水题选做
为什么是水题选做呢?因为我只会水题啊 ( 为什么是$Atcoder$呢?因为暑假学长来讲课的时候讲了三件事:不要用洛谷,不要用dev-c++,不要用单步调试.$bzoj$太难了,$Topcoder$整 ...
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- 贪心/构造/DP 杂题选做Ⅱ
由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...
- [SDOI2016]部分题选做
听说SDOI蛮简单的,但是SD蛮强的.. 之所以是选做,是因为自己某些知识水平还不到位,而且目前联赛在即,不好花时间去学sa啊之类的.. bzoj4513储能表&bzoj4514数字配对 已写 ...
- 贪心/构造/DP 杂题选做
本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...
- 『CUDA C编程权威指南』第二章编程题选做
第一题 设置线程块中线程数为1024效果优于设置为1023,且提升明显,不过原因未知,以后章节看看能不能回答. 第二题 参考文件sumArraysOnGPUtimer.cu,设置block=256,新 ...
- [NOIP2017(TG/PJ)] 真题选做
[NOIPTG2017] 小凯的疑惑 题意 小凯有两种面值的金币,每种金币有无数个,求在无法准确支付的物品中,最贵的价值是多少金币. 分析 设两种金币面值分别为 $a$ 和 $b \; (a<b ...
- 期望dp好题选做
前言: 最近连考两场期望dp的题目,sir说十分板子的题目我竟然一点也不会,而且讲过以后也觉得很不可改.于是开个坑. 1.晚测10 T2 大佬(kat) 明明有\(O(mlog)\)的写法,但是\(m ...
- 课后选做题-MyOD
课后选做题-MyOD od命令的了解 功能 od命令用于将指定文件内容以八进制.十进制.十六进制.浮点格式或ASCII编码字符方式显示,通常用于显示或查看文件中不能直接显示在终端的字符.od命令系统默 ...
随机推荐
- 简单说一下UWP中的JumpList
在Windows10的10856这个版本中,微软为桌面版提供了一组新的应用交互方式,磁贴和Toast通知的个性化都有了一定的改善.针对磁贴方面,微软为我们提供了一组新的API来扩充我们对应用的交互方式 ...
- 前端面试(原生js篇) - 精确运算
一.面试题 问:开发的时候有用到过 Math 吗? 答:很多啊.比如生成 GUID 的时候,就会用到 Math.random() 来生成随机数. 问:别的呢?比如向下取整.向上取整? 答:向下取整是 ...
- 关于Ajax的get与post浅分析,同步请求与异步请求,跨域请求;
Ajax局部异步刷新全称ASynchronous JavaScript And XML.使用Javascript代码获取服务器的数据,Ajax当中有两个请求方法,一个是get方法,一个是post请求方 ...
- docker 安装jenkins
基于docker 进行安装 软件,首先需要有docker环境. 1.docker 下载 jenkins 镜像 指定版本 ,因为低版本的后面安装 软件会失败(亲测). docker pull jenki ...
- 纯小白入手 vue3.0 CLI - 3.1 - 路由 ( router )
vue3.0 CLI 真小白一步一步入手全教程系列:https://www.cnblogs.com/ndos/category/1295752.html 尽量把纷繁的知识,肢解重组成为可以堆砌的知识. ...
- mysql插入表数据中文乱码问题解决方案
一.问题 开发中遇到将其它数据库数据插入到mysql数据库表中一直会报类似如下错误: Incorrect string value: '\xE6\x88\x91' for column 'name' ...
- SEO高手和SEO屌丝的八个区
原文:http://www.it28.cn/sousuoyinqing/853085.html SEO这个行业并不规范,有些seo工程师可以拿着高薪,进行一些大型网站的seo工作,其实主要是UEO的工 ...
- 使用volley上传多张图片,一个参数对应多张图片,转载
https://my.oschina.net/u/1177694/blog/491834 原帖地址 而如果使用volley的话,因为请求数据那些都很简便,但遇到上传文件就麻烦那可不好,同时使用多个网络 ...
- WCF服务端开发和客户端引用小结
1.服务端开发 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序 ...
- MySQL GTID复制错误处理之跳过错误
某Slave报错信息: mysql> show slave status\G; mysql> show slave status\G; ************************** ...