[NOIP2017]列队(线段树/裂点splay)】的更多相关文章

考虑n=1的做法,就是支持: 1.在线删一个数 2.在结尾加一个数 3.查询序列的第y个数 用线段树记录区间内被删元素的个数,可以通过线段树上二分快速得解,对于新增的数,用vector记录即可. 对于满分同样如此,对每行开一个线段树,再对最后一列单独开一个. 对于每次操作: 若在最后一列:就是对最后一列直接使用n=1的做法. 若不在:对第x列的前m-1个用n=1的做法,再将最后一列的第x个加入第x列的末尾,然后再对最后一列使用n=1的做法. #include<cstdio> #include&…
---题面--- 题解: 之前写的splay,,,然而一直没调出来,我感觉是某个细节想错了,,然而已经重构4次代码不想再写splay了.于是今天尝试了线段树的解法. 首先因为每次出列之后的变化都是将当前行左移,然后将最后一列上移,所以最后一列不适合和其他的行放在一起处理. 因此对于每行的前m - 1位开一棵线段树,对于最后一列开一棵线段树. 但是因为空间开销过大无法承受,因此考虑动态开点.一开始每棵线段树内只有一个节点,这个节点代表了当前行1 ~ m - 1的所有节点. 如果我们要从中删除一个节…
我写的是线段树套splay,网上很多人写的都是套treap,然而本蒟蒻并不会treap 奉上sth神犇的模板: //bzoj3196 二逼平衡树,支持修改某个点的值,查询区间第k小值,查询区间某个值排名,查询区间某个值值前驱.后继.查询第k小值是log^3(n)的,其他都是log^2(n)的 #include <cstdio> using namespace std; ,inf=; ],root[],left,right,tot,son[maxn][]; int mmin(int x,int…
传送门 题意 给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种: 查询 $ k $ 在区间 $ [l,r] $ 内的排名 查询区间 $ [l,r] $ 内排名为 $ k $ 的值 将 $ a[p] $ 修改为 $ k $ 查询 $ k $ 在区间 $ [l,r] $ 内的前驱(前驱定义为小于 $ k $ ,且最大的数) 查询 $ k $ 在区间 $ [l,r] $ 内的后继(后继定义为大于 $ k $ ,且最小的数) ​ 题解 线段树套splay. ​…
题目: Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查询k在区间内的后继(后继定义为大于x,且最小的数) Input 第一行两个数 n,m 表示长度为n的有序序列和m个操作第二行有n个数,表示有序序列下面有m行,opt表示操作标号若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r…
题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n \times mn×m 名学生,方阵的行数为 nn ,列数为 mm . 为了便于管理,教官在训练开始时,按照从前到后,从左到右的顺序给方阵中 的学生从 1 到 n \times mn×m 编上了号码(参见后面的样例).即:初始时,第 ii 行第 jj 列 的学生的编号是 (i-1)\times m + j(i−1)×m+j . 然而在练…
题意: 完成两个操作: 1.询问一个区间里第k小的数: 2.修改数列中一个数的值. 分析: 线段树套平衡树,线段树中的每个节点都有一棵平衡树,维护线段树所记录的这个区间的元素.这样处理空间上是O(nlogn)的,因为线段树有logn层,每层的平衡树所记的节点总数都有n个.修改很容易想到,把所有包含要修改点的区间的平衡树都修改了就行了 查询使用二分答案的方法 // File Name: 2112.cpp // Author: Zlbing // Created Time: 2013年10月07日…
题目链接 幸甚至哉,歌以咏志. 拿下了曾经是那么遥不可及的线段树,学会了曾经高不可攀的平衡树,弄懂了装B的时候才挂在嘴边的树套树. 每道模板都是链上的一颗珠子.把它们挨个串起来,就成为我成长的历程. 抒情结束开始讲题 这道题我们用线段树存平衡树的根节点.比如我们有一棵线段树 这样子.线段树的一个节点   存   它表示的那个区间   所对应的  平衡树   的根节点编号.这样每个节点都拥有一棵平衡树.是不是很炫呢? 对于操作1我们就可以把所有零散的区间里比它小的数的个数都找出来,+1就是答案啦.…
四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog(n)^{2}) $ #include<iostream> #include<cstdio> using namespace std; const int N=50005,T=2500250,inf=1e9; int n,m,a[N],rt[T],tot,mn=inf,mx=-inf;…
传送门 至少BZOJ过了,其他的直接弃. 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱定义为小于x,且最大的数) 5.查询k在区间内的后继(后继定义为大于x,且最小的数) 最外层套一颗线段树,用来表示区间,线段树下面套个splay用来维护当前线段树节点的区间. 对于第二问可以二分,看看哪个数的排名为 k. ——代码 #include <iostre…
P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在区间内的前驱(前驱定义为严格小于x,且最大的数,若不存在输出-2147483647) 查询k在区间内的后继(后继定义为严格大于x,且最小的数,若不存在输出2147483647) 注意上面两条要求和tyvj或者bzoj不一样,请注意 输入输出格式 输入格式: 第一行两个数 n,m 表示长度…
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1901 给出一个长度为n的数列A,有m次询问,询问分两种:1.修改某一位置的值;2.求区间[l,r]内的第k小的值. 1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6716  Solved: 2793[Submit][Status][Discuss] Description 给 定一…
4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status][Discuss] Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线.奈特公司纪律森严,每 名情报员只能与自己的上.下线联系,同时,情报网络中仟意两名…
题面 线段树入门题. 我们考虑线段树来维护这个矩阵. 首先我们先定n+1棵线段树前n棵维护每行前m-1个同学中没有离队过的同学,还有一棵维护第m列中没有离队过的同学.再定n+1棵线段树前n棵线段树维护每行因一个同学离队而从第m列插♂进来的同学,还有一棵维护到队尾的同学. 具体怎么维护?比如当前的询问是(x,y),先分两种情况: 1.不在第m列. 那么我们就先看看这个同学是不是插♂进来,是的话就在那后n+1棵线段树的第x棵里找,不然就在前n+1棵的第x棵里找. 然后在对应线段树的对应位置里删除离队…
题目:https://www.luogu.org/problemnew/show/P3960 NOIP 题,不用很复杂的数据结构...但又参考了许多: 要求支持维护删除第 k 个和在末尾插入的数据结构,线段树就很好: 所以每行一个线段树维护前 m-1 个元素,最后一列一个线段树即可: 但 n+1 个线段树显然空间太大,考虑利用一开始是按顺序排列的特点: 也就是不用实际开出来所有线段树的点,只要它是满的就可以直接算出来: 对于新加入线段树的点,如果真的加入线段树里,又不会算空间了... 但是新加入…
今天调了一个早上哈哈哈,不过因为\(Splay\),常数比较大 洛谷的评测记录: \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long #define mid (l+r>>1) using namespace std; const int maxn=4000010; const int inf=2147483647; int n,m,sz,ans,Max; int a[maxn],ch[maxn][2],fa[…
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱定义为小于x,且最大的数) 5.查询k在区间内的后继(后继定义为大于x,且最小的数) Input 第一行两个数 n,m 表示长度为n的有序序列和m个操作 第二行有n个数,表示有序序列 下面有m行,opt表示操作标号 若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间…
定义第i行为所有的点(i,j),0<j<m 可以发现,每一行是相对独立的,每一次操作只会影响到当前行和最后一列 考虑每一行和最后一列各开一个树状数组,但这样显然会爆空间 实际上,对于没有离队过的点是没必要储存的,可以直接算出编号, 因此只要用vector储存每一行和最后一列后加入的点即可 还需要预处理一个数组d[i]表示第i次询问当前行的离队的点的纵坐标 这个可以离线做出来,然后只需要对最后一列维护一个树状数组即可 Code #include <cstdio> #include &…
如题,这是一个模板... #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cctype> #define max(x, y) (x > y ? x : y) #define min(x, y) (x < y ? x : y) inline void read(int & x) { x = ; ; ch…
study from: https://tiger0132.blog.luogu.org/slay-notes P3369 [模板]普通平衡树 #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> using nam…
0 写在前面 怎么说呢,其实从入坑线段树一来,经历过两个阶段,第一个阶段是初学阶段,那个时候看网上的一些教学博文和模板入门了线段树, 然后挑选了一个线段树模板作为自己的模板,经过了一点自己的修改,然后就已知用着,其实对线段树理解不深,属于就会套个模板的状态,期间有人问我线段树的问题,我其实也半知不解的, 后来,刷了几道DFS序+线段树的题目,那个时候多多少少有所长进,再次回过头来重新看线段树的代码,理解有所加深,算是勉强理清了线段树这个东西, 再到现在,前不久刚把splay搞完,对平衡二叉搜索树…
之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池..尼玛终于过了..附zju2112代码于后. bzoj倒是过了,1A的感觉还是很爽的..可是时间不好看..这就是所谓\(O(nlog^3n)\)的复杂度的可怜之处么? 写挂的地方: insert一定要是传地址指针进去. delete时先把地址指针delete掉,最后把是地址指针指向左儿子or右儿子…
题解 是我从来没有做过的裂点splay... 看的时候还是很懵逼的QAQ. 把最后一列的$n$个数放在一个平衡树中, 有 $n$ 个点 剩下的$n$行数, 每行都开一个平衡树,开始时每棵树中仅有$1$个点, 记录了开始时的区间左端点 $1$ 和右端点$m - 1$. 这样每次出队都最多只会影响两棵平衡树, 其中一颗为表示最后一列的平衡树. 然后就可以分成两种情况进行处理 1. $y = m$ 即出队的人位于最后一列,那么仅会影响最后一列的那颗平衡树, 删除位于第$x$个位置的点, 再插入到最后即…
正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法,我目前是先只写个最傻逼的方法,等学了splay什么的再来upd一下QAQ(这题好像有,线段树.树状数组.splay等各种方法,我可能都会写只要我麻油咕QAQ 然后就直接进入正题QAQ 首先其实要知道动态开点线段树和线段树思想什么的都是一样儿的,只是实现方法有一点儿区别(就是动态开点线段树节省点儿空间…
令splay中的一个点表示一段区间,需要使用其中某个点时将区间分裂即可,剩下的都是splay的基本操作了.写的非常丑陋,注意细节.感觉考场上肯定只能靠部分分苟活了.想起来去年因为各种莫名其妙的原因50->0 考虑一维时的线段树做法.维护区间内有多少人,每次找到第x个人把他拿出来放到最后就行了.扩展到二维动态开点即可.不写了 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib…
题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数为 nn,列数为 mm. 为了便于管理,教官在训练开始时,按照从前到后,从左到右的顺序给方阵中 的学生从 1 到 n \times mn×m 编上了号码(参见后面的样例).即:初始时,第 ii 行第 jj 列 的学生的编号是(i-1)\times m + j(i−1)×m+j. 然而在练习方阵的时候…
维护一个方阵,支持 1.删掉一个点,剩下的点先向左看齐再向前看齐 2.询问一个位置上是哪个点 $n,m,q \leq 3 \times 10^5$ sol: 我们每行前$m-1$列维护一个线段树,最后一列维护一棵线段树 然后搞n + 1个vector 这个线段树只需要维护“这个节点下面有多少点已经被删除了” 删除最后一列时,删掉一个点然后pushback即可 非最后一列时,删掉这个点,把它加到最后一列最下面,然后把本来应该在这个位置的数放到这一行最后就可以了 之前写过splay...线段树好写好…
题目链接 题意不说了,一辈子也忘不掉 解法1.平衡树 这题就是平衡树裸题,每一行开一棵维护前 \(m-1\) 个,最后一列单独维护,因为很多人没有用到,所以平衡树每个节点是一个区间(pair),分裂时顺便把区间裂开来.这也是最暴力的解法 这里以Fhq_Treap为例(其实是我不熟练Splay) //Fhq_Treap //http://uoj.ac/submission/296955 #include<stdio.h> #include<cctype> #include<cs…
嘛..两年前的题目了,想起第一次参加提高组还骗了一个省二回来呢...跟同学吹了好久的... 离退役又近了一骗博客啊.. 闲聊结束. 照常化简:给定一个1-n*m编号的矩阵,每次删除一个位置,然后左边向右补,之后后面向前补,最后空出来的位置再由刚刚删去的点补上,求每次删除的点的编号. 当年也是暴力,奔着30pts就去了,结果奈何手欠数组开大了全部MLE... 但是正解也就从这里延伸. 首先,直接地,删除,增加,维护序列,能想到的东西差不多就是平衡树了... 但是,考场上大打Splay绝对不可能(日…
原文链接https://www.cnblogs.com/zhouzhendong/p/9265380.html 题目传送门 - 洛谷P3960 题目传送门 - LOJ#2319 题目传送门 - Vijos P2033 题意 懒了,不概括了. 题解 一开始写了树状数组. 算法非常真,写完全部 WA,但是漏了一步,我快写吐了,于是弃疗之后从某度*了一份代码. 我来说说线段树的做法: 线段树动态开点,每行一个线段树,最后一列一个线段树. 线段树要支持找区间第 $k$ 大,这样方便找出指定位置. 注意一…