CDQZ.OPENJUDGE DataStructure22
我觉得这是很重要的一些题目。它们都在这里:硕巨结构
Challenge 0:给定数列,单点修改,单点查询修改。煞有介事,不过一数组耳。
Challenge 1:给定数列,单点修改,单点查询第k次操作后的值。当时写了链表,显然可以被卡。lemonoil说写主席树才是正道,其实不然。使用vector<pair<int,int> > ...[n]就可以了。插入显然都是有序的,查询直接二分就好了。
Challenge 2:数列最开始是空的,允许在最后插入一个数,单点询问,或撤销若干次操作(包括撤销与插入操作)。主席树很好写,主要是考察对“撤销”的理解(最开始就是不懂“撤销”,以为是直接把顶上的东西丢了)。其实不管插入还是撤销,总的操作数都加了1。而插入是基于前一次操作再加入一个数,而撤销是把若干次以前的再搬回顶上。使用一个len来辅助维护数列的长度。
Challenge 3:给定数列,单点修改,区间查询和。树状数组就好了,不必写线段树。
Challenge 4:给定数列,单点修改,区间查询相邻两数乘积和,区间查询任意两数乘积和,%1e9+7。记得这个当时调了很久很绝望,但最后发现错误很小很微不足道,就是所有单点的值都应该%MOD+MOD%MOD。因为如果不把这些数标准化,得到的也不会是标准的结果。而当时写struct写的很痛苦,后面写的直接把pair给typedef了,再加上预带的merge函数下面就可以变得很清新。这种套路也出现再IDY4月份的有序链剖中。
Challenge 5:给定数列,区间修改成同一个数,区间查询和。线段数的模板题,看似很简单。但就是这样的题目也是有坑点的。因为修改成的数可以为所欲为,所以常规状态下的什么-1就是大错特错了。要么再加一个bool变量,要么让flag的初始值变成绝对不可能取到的值。
Challenge 6:这道题目就是BZOJ2957楼房重建。IDY4月份当时还考过这道题目的进阶版本:单点修改,区间询问。首先,每个线段存的是区间最大值与区间可以看见的数目。而又有一个很重要的内函数,询问一个线段中高度>h的楼房数,也是二分(或分治)递归单次O(lgn),中间还是很有机巧的(充分利用题目性质)。这个东西在query和update都用得很多,于是整个是O(nlg2n)的。
而全局询问和区间询问的差别在哪里?对于后者,IDY的做法是把覆盖线段通通fetch出来再for一遍;而QJX告诉我,其实直接搞就是了。对于跨中点的询问,先处理左边,修正一下影响再处理右边,好像有一点CDQ的意思。
而此题其实可以区间修改。区间修改包括区间修改为同一个值和区间同增同减,我通常的做法是使用“kill”来打扫干净屋子再请客,而中间的顺序是很有意思的。最后写出来很长,大概可以用来考后来人了。
另外,此题使用分块也是可以的。
Challenge 7:给定数列,单点修改,询问一个数出现的次数。使用map可以过,但最开始使用multiset却稳稳的TLE。先以为是count过慢(但count确实非常慢),但直到做完Challenge 8才知道是为什么。
但COUNT确实很慢,我在自己的机子上试了一下这段代码:
#include <cstdio>
#include <set>
#include <ctime> std::multiset<int> st;
int main() {
for( int i = , j; i <= ; i++ ) {
if(i%==) printf("%d %d\n",i,clock());
st.insert();j=st.count();
}
printf("%d\n",clock());
}
得出了这样一张表:
进行n次插入与count | 时间(ms) |
1000 | 5 |
5000 | 101 |
10000 | 407 |
20000 | 1631 |
40000 | 6708 |
60000 | 15261 |
80000 | 28005 |
100000 | 43916 |
Challenge 8:给定一个集合,允许删除或插入数(不可重),询问集合中任意两数差绝对值的最小值。使用1个set存数字,1个multiset存答案。中间有曾经XGG那道巡游和YALI那道容斥集合的影子。但是最开始交上去直接TLE了,本地测试发现插入仅10000个数就会TLE,再排查就发现去掉lower_bound速度会快上很多很多很多倍。于是整个人迷惑了,不是O(logn)的么?在网上查,找到了一篇很好的博客:std::set::lower_bound与std::lower_bound的效率问题。长见识了,所以不应该std::lower_bound(st.begin(),st.end(),...)了,而是应该st.lower_bound(...)啊。
Challenge 9:给定数列,单点删除,询问单点。典型的简单平衡树。
Challenge 10:给定数列,单点修改,询问全局第k大。使用值域线段树或是平衡树。值域线段树需要注意对边界的处理(就像cheese那样虽然最后数据很水),使用-0x7fffffff~0x7fffffff是1000ms,使用0~0xfffffffe用unsigned大概快50~100ms。而平衡树可以不用建新节点,把原来的取出来,让它变成叶子结点(我在做phalanx的时候就是忘了改它的左右儿子和siz),再插回去。快得多,只要了380ms,但代码长度大约90行比线段树多一半。
Challenge 11:简单主席树。ZJC说可以用“可持久化树状数组”。
Challenge 12:经典题目。区间第k大无修改无插入。使用树状数组+线段树固然可以,但毕竟是O(nlog2n)的,时间4159ms,空间也大的吓人(开始就是空间开小了RE)。只使用主席树虽然无法修改,但复杂度就是O(nlogn)的了,时间1048ms。如果使用莫队,因为还是需要辅助数据结构,而O(nsqrtnlogn)素来是跑不过100000的。但是,这样就完了?不不不。还有一种神方法。使用区间线段树,每个线段一个vector,build的时候自下向上进行归并。查询的时候把log个线段搞出来,外面二分答案,内部for一遍加上upperbound。看上去是O(nlg3n)的,但其实就应该是O(nlg3n)的。但是数据如果强度不够高,水过去还是可以的。
CDQZ.OPENJUDGE DataStructure22的更多相关文章
- jubeeeeeat
http://cdqz.openjudge.cn/2016/0003/ 总时间限制: 1000ms 内存限制: 256000kB 描述 众所周知,LZF很喜欢打一个叫Jubeat的游戏.这是个音乐游戏 ...
- OpenJudge cdqz/Data Structure Challenge 2 (Problem 5822) - 可持久化线段树
描述 给一个空数列,有M次操作,每次操作是以下三种之一: (1)在数列后加一个数 (2)求数列中某位置的值 (3)撤销掉最后进行的若干次操作(1和3) 输入 第一行一个正整数M. 接下来M行,每行开头 ...
- 【openjudge】 CDQZ challenge 4
改了三天,提交17次,一定要纪念一下! 1004:Challenge 4 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 262144kB 描述 给一个长为N的数列 ...
- 记一周cdqz训练
#include <cstdio> using namespace std; int main(){ puts("转载请注明出处:http://www.cnblogs.com/w ...
- 【OpenJudge 8463】Stupid cat & Doge
http://noi.openjudge.cn/ch0204/8463/ 挺恶心的一道简单分治. 一开始准备非递归. 大if判断,后来发现代码量过长,决定大打表判断后继情况,后来发现序号不对称. 最后 ...
- 【OpenJudge 191】【POJ 1189】钉子和小球
http://noi.openjudge.cn/ch0405/191/ http://poj.org/problem?id=1189 一开始忘了\(2^{50}\)没超long long差点写高精度Q ...
- 【OpenJudge 1665】完美覆盖
http://noi.openjudge.cn/ch0405/1665/?lang=zh_CN 状压水题,手动转移 #include<cstdio> #include<cstring ...
- 【OpenJudge 1793】矩形覆盖
http://noi.openjudge.cn/ch0405/1793/ 好虐的一道题啊. 看数据范围,一眼状压,然后调了好长时间QwQ 很容易想到覆盖的点数作为状态,我用状态i表示至少覆盖状态i表示 ...
- OpenJudge 2990:符号三角形 解析报告
2990:符号三角形 总时间限制: 1000ms 内存限制: 65536kB 描述 符号三角形的第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“ ...
随机推荐
- CSharp 案例:用 Dynamic 来解决 DataTable 数值累加问题
需求说明 给定一个 DataTable,如果从中取出数值类型列的值并对其累加? 限制:不知该列是何种数值类型. 解决方案 1.将表转换为 IEnumerable<dynamic>,而后获取 ...
- python基础学习笔记(三)
序列概览 Python 包含6 种内建的序列,这里重点讨论最常用的两种类型:列表和元组. 列表与元组的主要区别在于,列表可以修改,元组则不能.也就是说如果要根据要求来添加元素,那么列表可以会更好用:而 ...
- 《Linux内核设计与实现》课本第四章学习总结
进程调度 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统. 多任务系统分为两种: 抢占式多任务:Linux提供了抢占式的多任务模式,由调度程序来决定什么时候停止一个进程的运行 ...
- 在Eclipse中使用JUnit4进行单元测试(图文教程一)
在Eclipse中使用JUnit4进行单元测试 单元测试,JUnit4. 这两个有什么关系呢?这就好比(草)单元测试和(割草机).用这个JUnit4工具去辅助我们进行测试.其实不理解这个也没关系,听多 ...
- HDOJ1287_破译密码
一道正常简单题 曲折解题 做这题的时候看了很久没有看懂是什么意思,最后以为是一道单独的数学题把B这个大写字母猜出来进行异或运算,还不知道C里面异或运算可以直接有符号的:),导致又去学习了一下十进制转换 ...
- css - 背景图片充满整个屏幕
body { /* 加载背景图 */ background: url("../static/images/index/backImg.jpg") no-repeat; /* 背景图 ...
- PAT 1011 A+B和C
https://pintia.cn/problem-sets/994805260223102976/problems/994805312417021952 给定区间[-2^31^, 2^31^]内的3 ...
- TCP 三次握手理解和过程
1:TCP为什么要三次握手,不是两次四次? 2:TCP协议三次握手过程分析
- SQLSERVER 备份数据库的注意事项
1. SQLSERVER 有一个压缩备份集的功能,能够实现大概15%的压缩比(跟数据类型不同而不同) 之前竟然没发现...浪费了好多磁盘资源.. 多学习多思考..
- Delphi7/2007/2009/2010/XE/XE2/XE3/XE4/XE5/XE6/XE7/XE8/10最终版
RAD Studio 10.1 Berlin(with Update1)http://altd.embarcadero.com/download/radstudio/10.1/delphicbuild ...