![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构
文章平均质量分 50
stduy_ing
这个作者很懒,什么都没留下…
展开
-
蓝桥杯 - 游园安排【第十一届】(最长上升子序列 + 线段树)
链接:游园安排【第十一届】题意:思路:首先,读懂题意后发现就是求最长上升子序列,但是数据有1e6,并且要求字典序最小。那么我们可以用线段树维护当前最长上升子序列并且同时维护当前最小串。1 .我们从后往前遍历,对于当前位置,找到后面的长度最大并且名字最小的位置,这样维护出来的串就能保证字典序最小了。2.还需要记录答案,我们只需用一个数组记录每一个名字后面跟的是哪一个名字即可。最后找到长度最大且开头最小的位置,循环一遍即可。代码:.........原创 2022-06-14 21:51:35 · 528 阅读 · 1 评论 -
蓝桥杯 - 第十三届省赛真题-选数异或(线段树 + 离线)
链接:第十三届省赛真题-选数异或题意:思路:对于区间[l ,r]中要想找到两个数异或和为x,那么就要存在两个位置pos1,pos2pos1,pos2pos1,pos2满足apos1==apos2⨂xa_{pos1}==a_{pos2}\bigotimes xapos1==apos2⨂x,那么问题就变成了对于每一个位置找区间内是否存在对应另一个数。考虑离线,对 r 排序,线段树的权值表示对于当前r,当前位置到r是否存在两数异或和为x。对于某一个位置 pos,如果前面出现过apos1==apos原创 2022-05-31 09:22:26 · 531 阅读 · 0 评论 -
优先队列实现
学习了一下堆排序,记录一下实现优先队列的代码:#include<bits/stdc++.h>#define ll long long#define fi first#define se second#define pii pair<int,int>using namespace std;const int maxn=1e5+5,mod=1e9 + 7;class Priority_queue{public: int a[maxn] , sz = 0;原创 2022-03-03 21:53:12 · 99 阅读 · 0 评论 -
蓝桥杯国赛 奇偶覆盖(线段树 + 扫描线)
链接:奇偶覆盖题意:思路:扫描线模板,维护有一点区别,分别维护当前节点下被覆盖奇数次和偶数次的长度。然后离散化一下(注意把数字离散化实质上是把每一段区间看成一个点)。代码:#include<bits/stdc++.h>#define ll long long#define fi first#define se second#define pii pair<int,int>using namespace std;const int maxn=1e5+5,mod=9原创 2022-02-25 22:07:09 · 678 阅读 · 0 评论 -
2021牛客暑期多校训练营7 K - xay loves sequence(主席树 + 三分)
题意:每次可以选择一个子区间使其+1或-1后对k取模,问把区间内所有数变为0的最小操作次数。思路:感觉碰到过很多次,最近的沈阳 J 题,还有西安邀请赛的B也是类似的题。如果不考虑取模,那么求出差分数组 d,问题转换为每次操作对d数组的一个数+1,一个数-1。那么肯定是对正数+1,负数-1,那么答案就是所有数的绝对值之和除2.考虑取模,那么相当于对每个数 + k或者 - k,要使贡献减小,必然是对负数 + k ,整数 - k 。此时每个数的贡献变化量为 k−2∗∣d[i]∣k - 2 * |d[原创 2021-11-24 22:02:17 · 263 阅读 · 0 评论 -
Gym 103373 - problem - F. Flip (线段树区间合并)
链接:F. Flip题意:给出一个01串,有两种操作:查询区间内01交替的子区间的数量。将区间内的01反转。思路:线段树维护区间左右端点分别是什么,该区间的合法子区间的数量,以左右端点为起点的最长合法区间的长度。区间合并的时候如果两个端点不同可以增加贡献。注意查询的时候用类似于pushup的操作,没找到一个小区间合并到答案里。代码:#include<bits/stdc++.h>using namespace std;#define ll long longconst i原创 2021-11-09 22:05:48 · 232 阅读 · 0 评论 -
HDU 6992 Lawn of the Dead (线段树)
链接: Lawn of the Dead题意:有一个大小为n∗m(1≤n,m≤1e5)n * m(1\leq n,m\leq1e5)n∗m(1≤n,m≤1e5)的网格图,初始在点(1,1)(1 , 1)(1,1),只能向下和向右走 , 现给出 k 的点的坐标 , 代表这 k 个点不能走 , 求图中有多少个点可到达。思路:如果一个点不可达 , 那么它上方和左边的点一定不可达 ,所以我们从上到下维护每一行可达的点有哪些 , 对于如果当前在第 i 行 , 点ai,ja_{i ,j}ai,j和点ai,ka原创 2021-07-30 14:38:52 · 262 阅读 · 0 评论 -
Leetcode 5696. 统计异或值在范围内的数对有多少 (字典树)
链接: Leetcode 5696题意:给出一个 num 数组 , 和 low ,high,求数组中有多少个点对(i , j)满足 num[i] ^ num[j] ≥\geq≥ low && num[i] ^ num[j] ≤\leq≤ high.思路 :求异或值满足一个范围,肯定是字典树 , 我们可以对每一个数单独考虑。对于每一个数,从高位开始,如果某一位的运算结果大于 low 那后面的 就可以随便是什么了,high也同理 , 所以只要递归往后找每一位,并维护 两个条件 ,当前是原创 2021-03-25 22:16:28 · 213 阅读 · 3 评论 -
2021牛客暑期多校训练营4 E - Tree Xor(合法异或区间)
链接:E - Tree Xor题意:有一颗节点数为 n 的树 , 现给出每个节点权值的范围 [li,ri][l_i , r_i][li,ri],以及每条边两端点的异或和。求点的权值有多少种不同的取值。思路:首先我们可以发现确定一个点的权值后,所有的的权值就都确定了 , 所以我们先让1号节点的权值为 0 , 求出其它所有点的权值wiw_iwi。这样我们给1号节点异或上 a 后,就相当于给其它每个节点也异或 a 。这样我们就可以求出 a 的 n 个限制 wi⨁a∈[li,ri]w_i\bigop原创 2021-07-27 09:56:52 · 546 阅读 · 0 评论 -
HDU 6962 I love tree (线段树 + 树链剖分)
链接:I love tree题意:给一棵树 , 初始所有点的点权为 0 ,现有两种操作 :给出 a , b,把a 到 b路径上的点依次加上 1 ^ 2 , 2 ^ 2 , 3 ^ 2。给出一个 a 求点 a 的权值。思路:如果是一个普通的数组进行上述修改操作 , 我们有两种方法 , 观察上述操作,发现加上的值差分后是一个等差数列 , 所以我们把原数组差分,把操作数也差分一下,就变成区间维护一个等差数列,一个点的答案就是前缀和。但是这是在树上 , 感觉就不太好操作了,多校的题解说是要分块。原创 2021-07-23 10:45:01 · 490 阅读 · 0 评论 -
HDU-6959-zoto(莫队 + 分块 / 数状数组)
链接: HDU-6959-zoto题意:给出一个数组 a[i] , 表示平面内有 n 个点,每个点的坐标为(i, a[ i ]),再给出 m 次查询,每次查询给出一个(x0 , y0) , (x1 , y1)的矩形区域 , 问矩形区域内有多少个不同的 y 坐标。题意简化一下: 求区间 [x0 , x1] 内大于等于 y0,小于等于 y1的不同的数有多少个。思路:对于不同的区间 [x0 , x1]可以用莫队来移动,先确定一个区间,每次移动我们需要修改对应点的个数, 如果这个数的个数从无到有 ,或者从原创 2021-07-20 20:50:51 · 308 阅读 · 5 评论 -
Gym-103145-problem-D. Lowbit (吉司机线段树)
链接:D. Lowbit题意:给一个长度为n的数组a,有以下两种操作:给出l , r 把区间[l , r]内的每一个ai变成 a[i] + lowbit(a[i]).查询区间[l , r]的权值和。思路:对于某个数加上它的lowbit,如果这个数是 1000000(2)的形式,它的lowbit等于本身,那么等价于乘2。所以我们对区间打一个标记,如果全是上述形式,那么直接区间乘,否则就暴力更新。代码:#include <iostream>#include <cstdio原创 2021-07-14 20:57:59 · 590 阅读 · 0 评论 -
Gym - 102220 - problem H. Skyscraper (差分数组 + 线段树)
题意:有 n 座大楼排成一排,第 i 座大楼的预期高度为 ai,有m次操作:1.把区间[l , r]内的大楼的预期高度增加 k.2. 给定[l , r],查询仅对[l , r]区间内的大楼从0开始施工,到完成大楼修建至少需要多少个阶段。(每个阶段可以选择一个区间使得这个区间的大楼高度加1)思路:如果不考虑修改,j假设a的差分数组为数组b, 那么完成[l , r] 区间内的大楼修建需要 a[l] + b[l + 1 , r]中大于 0 的值之和。对于修改,其实我们只需要单点修改就行,每次区间修原创 2021-07-14 11:31:44 · 291 阅读 · 0 评论 -
HDU-5726-GCD(GCD预处理 + 线段树维护区间)
链接: HDU-5726-GCD题意:给你n个数(n<=1e5)然后m个询问(m<=1e5),每个询问一个区间,问你这个区间的GCD是多少,并且输出从1到n有多少个区间的GCD和这个区间的相同。思路:第一部分可以用线段树维护区间的GCD,第二部分,我们可以固定一个右端点,找出每一个gcd值变化的左端点,这个区间的长度就是区间gcd出现的次数。类似于递推的思路,具体看代码。代码:#include <iostream>#include <cstdio>#inc原创 2021-07-13 14:54:15 · 463 阅读 · 2 评论 -
洛谷 P4839 P哥的桶 (线段树维护线性基)
链接:P哥的桶 题意:给你 m 个位置和 n 次操作,操作有两种类型 :操作一 : 表示在区间[l , r]中选择任意个位置,使这些位置中的数的异或和最大。操作二 : 在位置 k 加入一个数x(每个位置可以有多个数)。思路:单点修改 + 区间查询首先考虑线段树 , 异或和最大考虑线性基。我们可以用线段树的每个节点表示这个区间的线性基,在修改的时候把每个包含这个位置的区间都插入一遍这个数就好了。然后查询可以把小区间的线性基合并到大区间,再根据这个大区间的线性基求解。代码:#include<原创 2021-03-17 19:19:34 · 139 阅读 · 0 评论 -
2020 江苏省赛 A. Array(线段树 + 欧拉降幂)
链接 A. Array题意:给你一个数组 , 有 5 种操作:【l , r】区间每个数 加 k 。【l , r】区间每个数 乘 k 。【l , r】区间每个数变成 它的 k 次方。求【l , r】区间每个数的 k 次方的 和(答案对p取模)。求【l , r】区间所有数的乘积(答案对p取模)。思路:一眼看上去,实在是太难维护了,有加法,还有k次方,但观察到 p 很小,最大是 30,所以取模后数组中的每个数最大不超过 30。所以我们可以用 30个线段树维护区间内 [0 , 30)的个数。原创 2020-12-03 10:27:46 · 411 阅读 · 0 评论 -
gym -101864 - B . A Leap of Faith (线段树求相交区间个数)
链接:B - A Leap of Faith题意:给 n 个 A类区间和 m 个 B 类区间,区间的左右端点为 l , r. 给出 q 次修改,每次询问加入一个 A 类区间或者 B 类区间,求每次修改后有交集的A 类与B类区间的对数。思路:求与 【l , r】区间相交的区间个数,可以先求出与它不相交的区间个数,也就是右端点比 l 小 ,或者左端点比 r 大的区间的个数(这个经常用),然后就可以用线段树维护,把区间的几个端点用4个线段树维护,就可以很快求出区间个数。所以初始答案,我们只需要遍历 n原创 2020-11-19 10:37:00 · 431 阅读 · 0 评论 -
2020 CCPC 威海 - G Caesar Cipher (线段树 + hash)
链接 : G Caesar Cipher题意 :给定一个数组 ,范围为 [0,65536),有以下两种操作:给出 x , y 把 [x , y] 内的每个数 + 1 同时对 65536 取模。给出 x,y,L , 查询区间 [x , x + L - 1] 和区间 [y , y + L - 1]是否完全相同。思路 :思路就是 线段树维护 hash ,有区间修改和查询 判断两段 hash值是否相同就可以了。首先考虑一下区间合并(也就是pushup),线段树的每个节点表示这一段的 hash原创 2020-10-29 11:10:52 · 699 阅读 · 6 评论 -
Codeforces 1430 - E. String Reversal(字符串 + 逆序对)
链接 E. String Reversal题意 :给一个长度为 n 的字符串 , 每次操作可以交换两个相邻的字符 , 要把字符串倒置过来,最少要多少次操作 。思路:下次看到这种交换相邻字符的题目, 一定要先想到逆序对,这里要把字符串倒置 ,最直观的想法是 n * (n - 1) / 2, 把它倒置过来 , 但是字符串里肯定有相同的字符 , 所以我们只要让相同字符的相对位置不变 , 这样一定是最小的 ,求出变化后的编号 ,求逆序对就好了。例如 aacbbb 一开始编号为 1 2 3 4 5原创 2020-10-13 09:56:59 · 655 阅读 · 0 评论 -
Codeforces Round #673 (Div. 2) E. XOR Inverse (字典树 + 分治)
链接 E. XOR Inverse 题意:给一个数组 ,需要找到一个 X ,使数组中每个数 异或 X 后 ,数组中的逆序对数最少 ,如果有多个 X 找最小的那个,求 X和逆序对数。思路:比较两个数的大小 ,其实就是比较两个数的二进制位第一个大小不同的位置的大小,因为字典树可以保存相同的前缀,所以我们先用字典树把这些数字存起来,用 vector 存一下当前前缀相同相同的每个数的位置。考虑每个二进制位 , 因为我们已经记录了这一位为 0 和 1 的数的位置,所以可以直接求出逆序对数 , 这样我们就原创 2020-09-28 15:14:05 · 423 阅读 · 0 评论 -
Codeforces 633 G. Yash And Trees (线段树 + bitset)
链接: G. Yash And Trees题意:给一棵以 1 为根的树,每个点都有一个权值,有两种操作:给 以 x 的子树下的节点权值增加 v 。查询 x 的子树下有多少个点的权值 a[i] % m 为素数。思路:观察到 m 的范围只有 1000 , 可以用二进制记录 每个数是否出现过,即线段树的每个节点表示 1000 个数出现了哪些 , 这样 pushup还是很好写 ,就是两个子区间的 | 值。这里用一个 bitset 存值就好了。和一个题目很类似 D. Distinct Charact原创 2020-09-27 10:36:46 · 218 阅读 · 0 评论 -
CSUST 4027 - 井底之蛙(线段树 / 吉司机线段树)
链接: :井底之蛙题意:n面墙按逆时针顺序编号 ,有两种操作每次把从 a - b (逆时针)编号的墙的高度减少 h ,如果当前高度小于 h 则变成 0 ;求 L- R 剩余墙的高度之和 。思路:一开始想的维护一个最大值和最小值,在更新区间时 ,如果当前最小值大于 h , 就用 lazy 标记更新区间 。如果 最大值小于 h , 把当前区间的值变为 0 。如果最大值为 0 ,直接返回。虽然这样会降低一些复杂度,但还是会 T .对于一些极限数据 如 0 , 1e9 ,0 ,1e9 ,0原创 2020-09-16 16:32:55 · 158 阅读 · 0 评论 -
Codeforce 787 D. Legacy ( 线段树优化建图 + 最短路)
链接: D. Legacy题意:一眼看上去是求最短路,但他给出的边权是,一个点到一个区间的边权(也就是说 u 到 【l,r】内的点都有一条边)。思路:因为区间内的点都是连续的,所以我们可以用线段树把这些连续的点缩成几个区间,把区间变成一个新的点,再让这个新点于原来的点之间连上权值为 0 的边,这样可以很大的降低复杂度。这个巨巨写得很详细 D. Legacy代码:#include <iostream>#include <cstdio>#include <map&原创 2020-07-29 16:30:45 · 324 阅读 · 0 评论 -
CSUST 2013 丢手绢 (线段树)
链接: 丢手绢题意:n个数编号为 1 - n 围成一个环,给出 q 次操作,点修改,和查询 相距不超过k的两个数字之和的最大值和最小值。思路:注意数据范围 k 最大是 5 ,我们可以 o ( n )的求出每个长度为 k 的区间里的 最大值次大值,最小值次小值,也就可以得到答案,但是还有修改,因为每次修改,最多改变 k 个区间的最值,所以我们还是可以直接修改这个小区间的最值 ,但这还不是我们要求的,我们可以把每个点的权值定义为 以当前位置为左边界长度为 k的区间的两数字之和的最大值,然后用线段树维护原创 2020-07-29 00:44:47 · 120 阅读 · 0 评论 -
HDU 6315 Naive Operations (线段树 特定区间 lazy )
链接: Naive Operations题意 :给定一个 b 数组 ,a 数组初始值为 0 ,两种操作:将 l - r 内 a数组的值+1。查询 l -r 内 a[i] / b[i] ( 取整)的和。思路:因为需要向下取整,不能直接利用 lazy 标记延迟下推,每次更新都要下推到底,这是最暴力的想法。但仔细想想 lazy 的用途,主要是为了在需要更新的时候再下推,在不需要更新时一直累计以减少时间复杂度。这题也可以利用这个思想,在 当前区间的所有 a[i] 值都小于对应的b[i]值时,对原创 2020-07-24 21:59:44 · 86 阅读 · 0 评论 -
CSUST 2033 大富翁 (离线树状数组 + 线段树求动态第 k 小)
链接: 大富翁题意:给一颗树 ,连接 n 个房间 ,n 个大富翁分别住在这 n 个房间,n 人 依次那 走第 k小的砝码 , k 的定义是 每个节点 的每个儿子节点及其对应子树中比当前节点权值大的节点数的最小值( 有点绕)。问每个人取走砝码的重量。思路:首先要解决的肯定是每个节点的子树内比父节点权值大的点的个数,也就是求给定区间内比 k 大的数的个数,这里不过是加了个 dfs 序,有很多写法 ,分块 ,离线树状数组,主席树?(这个貌似还不会),这里用了离线树状数组,离线树状数组,大概就是按权值原创 2020-07-23 20:31:54 · 151 阅读 · 0 评论 -
HDU 4417 Super Mario (分块+二分 / 离线 + 树状数组)
链接 Super Mario题意:给出一个数列,每次询问【l , r】中小于k的数有几个。思路:分块 ,其实就是一种暴力,不过用起来却很巧妙,就是把整个区间分成 sqrt(n) 块,然后对每个区间进行操作,统计答案。#include<iostream>#include<cstdio>#include<map>#include<math.h>#include<queue>#include<cstring>#in原创 2020-06-04 11:15:36 · 200 阅读 · 0 评论