万古神犇LXL,数据结构碾众生!
即使是蒟蒻也想变强啊..
luogu P3987 我永远喜欢珂朵莉~(这是题目名称!)
题目大意:
有一个长为n的非负数序列A,支持以下两个操作:
- 1 l r x : 把区间[l,r]中所有x的倍数/x
- 2 l r : 查询区间[l,r]的和
数据范围:
题解:
首先,这道题的突破口在这里:
一个数的约数个数不会太多。虽说上界
,但实际上远没有那么多。500000以内只有大概200个左右。当对值域进行限制的时候,很可能就与约数个数相关。尤其是,本题中还有很明显的x的倍数÷x的操作,可以考虑对每个可能的约数进行维护。鉴于单点修改,区间求和是
的,而一个数最多被除 次,总复杂度 这并不是制约复杂度的关键。而且,如果对于整个数列或分块以后的整块(本质上是一个“整体”)维护整体的信息的话,这题根本不可做了。必须找出需要被除的数,才能维护整个数列。现在问题是,如何快速找到需要被除的数。即,如何快速找到序列中x的倍数。可以考虑对所有 进行维护。对于每个约数,维护一棵平衡树,存储数列中它的倍数的下标。当进行区间除的时候,在对应的平衡树中找到下标在 之间的子树,进行dfs,并删掉所有操作进行后不再是x倍数的数的下标。这个过程中可以顺便维护数列值的变化。当然,并不需要建出所有的平衡树,只对查询的x建树就行了。说来惭愧,我这道题在看了lxl的题解后还改了好几天。我从这道题吸取的经验有以下几点:
- 当你的板子检查了很多很多遍都没发现问题时,很可能是main函数写错了(捂脸
- 各种最大值一定要弄清楚,例如我写题的时候就把值域最大值当成了n。
- 板子是可以根据自己的需要而改动的。如本题中平衡树并不需要维护size。
当然YNOI的毒瘤题需要一点卡常的小trick,相信大家都会,不再赘述。
我的代码:
1 |
|
luogu P5068[Ynoi2015]我回来了
题目描述
珂朵莉给你一个无向图,每次查询的时候给一堆二元组
输入输出格式
输入格式:
- 第一行三个数表示n,m,q
- n表示顶点个数,m表示边数
- 之后m行每行两个数x,y表示这两个点之间连有一条边~,边权都为1
- 之后q次询问,每个询问先给你一个数a
- 之后a行每行两个数,x,y,表示一个二元组
- n <= 1000 , m <= 100000 , q <= 100000
- a的和 <= 2100000
输出格式:
- q行,每行一个数表示这次询问的答案
题解:
这道题大概是YNOI中最良心的一道题?(雾 然而我也没做出来
首先,我们可以想到,这题大概要预处理,然后用接近(然鹅实际跑得飞快)其实暴力计算f就可以了~~
- 首先,跑n次bfs,计算出所有顶点对之间最短路。时间
- 然后,用已知的信息暴力更新f。设w为bitset的位宽,时间
- (逃
最后,毒瘤lxl卡了链式前向星,可以使用vector(因为空间够用,所以我直接开了邻接矩阵)
注意,输入存在重边。
所以,这道题我们就做完啦(撒花!
我的代码
(我以为这题一定很卡常,所以代码稍微毒瘤了一点):
1 |
|
luogu P5072[YNOI2015]盼君勿忘
题目描述
珂朵莉给了你一个序列,每次查询一个区间[l,r]中所有子序列分别去重后的和mod p
输入输出格式
输入格式:
- 第一行两个数
- 第二行
个数表示这个序列 - 之后
行,每行三个数 表示查询的区间与模数 - 对于
的数据, ,
输出格式:
行,每行输出一个数表示答案
题解
Orz lxl...由乃OI真的毒瘤。。。
我从不抄题解,我只是题解的搬运工。真的不会做,瞎写一点儿吧。
看到这题,没修改操作,数据范围1e5,可以想到这是个莫队题。然后我就不会了。
看到这样的题,我们暴力考虑每个区间显然是不现实的。我们转而考虑每个数对答案的贡献。对于一个数,它被计算到的次数可以这么计算:
对于一个区间
所以,我们用
上面的假做法只适合模数不变的情况。。。我们考虑模数会变化该怎么做。
手动划重点!以下内容的思想很重要!
考虑以虽然考试不让用这样就可以做到
最后还有一个小问题——如何快速求2的幂?模数动态改变,每次必须重新计算。有一种
设
我的代码:
(卡常的血泪史。。。)另外,好像对于值域比较大的情况,它会输出负数,现在暂时没找到原因。还有,膜运算真的太慢啦!去掉四个膜运算,运行时间几乎-1s。。
1 |
|
luogu P3674小清新人渣的本愿
题目描述
给你一个序列a,长度为n,有m次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ,这三个操作分别为操作1,2,3
选出的这两个数可以是同一个位置的数
输入输出格式
输入格式:
- 第一行两个数
- 后面一行
个数表示 - 后面
行每行四个数 表示这个是第几种操作, 表示操作的区间, 表示这次操作的
输出格式:
- 对于每个询问,如果可以,输出
,否则输出
题解
这题还是挺良心的比上一题良心多了 瞎说毒瘤lxl怎么会出良心题
没修改+1e5+lxl=膜队。
所以我们考虑怎么膜队维护。
我们首先肯定要维护所有数的出现次数。然后怎么做?
考虑暴力:对于每个可能成为答案的数,查询对应的另一个数是否存在。这个大概没法用什么数据结构优化了,所以考虑神奇的
- 对于询问1,若存在k和k+x,则对应着
。 - 对于询问2,若存在
,即 。对于负数,我们不好维护,所以用处理负下标的一般方法,转化成 。(此处N是一个较大的整数)这样,用另外一个 ,对于每个出现的 ,令对应的 下标处的值为1就可以了。另外, 的移位运算会将 强转成 ,当移位数为负数的时候会出锅。所以要手动把上面的左移改成右移,移位数取反。 - 对于询问3,我们发现我们用
没法很好的维护了。所以暴力枚举因子,判断是否存在,可以发现这并不是复杂度的瓶颈。这样做是正确的......
我的代码:
您看我如果不卡常的话码风还是挺正常的嘛
1 |
|
luogu P4688[YNOI2016]掉进兔子洞
题目描述
给定一个长度为n的数列,有m次询问。每次询问给出三个区间,询问若从这三个区间一起删数,一直删到三个区间没有共同的数为止,最后这三个区间一共剩下的数的数量。(询问之间互相独立)
题解
这道题的话,首先,还是经验公式:
没修改+1e5+lxl=膜队。
所以考虑怎么膜队。
首先通过补集转化,问题转化为三个区间共同出现的数的数量。既然是膜队,就要对每个区间分别处理。现在我们需要维护的信息就十分明确了:维护资瓷快速求交集的区间出现元素。这用数据结构并不好维护,所以考虑万能的此时情况开始变得辣手起来。。。
能不能通过某种手段,使得
才不是呢!lxl的题怎么能这么轻易做完?
我们发现我们的最终结果是保存在
我的代码:
1 |
|
Luogu P3793由乃救爷爷
题目大意:
随机数据下大数据RMQ. ## 题解 不知道为啥暴力建笛卡尔树dfs查会那么快...踩了lxl的标算... 万古神犇lch(大声)!
1 | // luogu-judger-enable-o2 |
Luogu P3934[Ynoi 2016]炸脖龙/Nephren Ruq Insania
和《相逢是问候》差不多,就不放题解了... 注意写法边界问题就好。
1 |
|
Luogu P5354[Ynoi2017]由乃的OJ/睡觉困难综合征
题意
有一棵无根树。每个结点有一个运算符(
*
其中,
题解
神仙题,蒟蒻不会/kel/kel
我们考虑链上的情况,做法是维护一个全0和全1的真值表,然后从高到低按位贪心。把它搬到树上,带修改,多次链询问,咋做啊?树剖嘛!然后呢?...
考虑维护什么信息才能得到路径上的真值表。不同位运算没有交换律,所以我们必须按照原顺序对运算进行处理..但是,一条树上路径可以拆分成
代码风格还可以吧
1 | // luogu-judger-enable-o2 |
v1.5.2