随笔分类 - 数据结构 树状数组
摘要:【题目】 "E. NN country" 【题意】给定n个点的树和m条链,q次询问一条链(a,b)最少被多少条给定的链覆盖。$n,m,q \leq 2 10^5$。 【算法】树上倍增+二维数点(树状数组) 先从半链角度考虑 。将每条给定链和每个询问拆成向上的一段和向下的一段。那么假设询问的半链最低端
阅读全文
摘要:【题意】阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。打字机上只有28个按键,分别印有26个小写英文字母和'B'、'P'两个字母。 经阿狸研究发现,这个打字机是这样工作的: l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后)。 l 按一下印有'B'的按键,打字
阅读全文
摘要:【题意】给定1~n的排列,m次操作每次删除一个数,求每次操作前的逆序对数。n<=10^5,m<=50000。 【算法】CDQ分治+树状数组 【题解】先树状数组求逆序对,然后统计每次删除的逆序对数。 每个数字及其坐标构成一个二维坐标,逆序对就是两个相对位置在左上右下的点,那么删除一个点会减少的逆序对就
阅读全文
摘要:【题目】F. Letters Removing 【题意】给定只含小写字母、大写字母和数字的字符串,每次给定一个范围要求删除[l,r]内的字符c(l和r具体位置随删除变动),求m次操作后的字符串。n<=2*10^5。 【算法】树状数组+平衡树(set) 【题解】因为坐标是序列变动后的,动态坐标可以转化
阅读全文
摘要:【题意】n*n的矩阵,初始值为0(题面有误),m次操作,增加一个格子的权值,或查询子矩阵和。n<=2*10^6。(m应该较题面所述偏大)。 【算法】CDQ分治(算法知识见数据结构) 【题解】三维偏序,一维排序扫描线(x坐标),一维树状数组前缀和(y坐标),一维CDQ分治(操作时间)。 每个矩阵查询差
阅读全文
摘要:【题意】给定ai,将1~n从小到大插入到第ai个数字之后,求每次插入后的LIS长度。 【算法】树状数组||平衡树 【题解】 这是树状数组的一个用法:O(n log n)寻找前缀和为k的最小位置。(当数列中只有0和1时,转化为求对应排名的数字,就是简单代替平衡树) 根据树状数组的二进制分组规律,从大到
阅读全文
摘要:【题意】给定三个长度为n的排列,求在三个排列中顺序相同的数对个数。 【算法】逆序对 【题解】很容易联想到NOIP火柴排队,涉及顺序问题显然和逆序对息息相关。 一个数对如果在三个排列中顺序不同,一定是1+2或2+1,也就是只在两数列之间顺序相同。 所以对三个数列两两求逆序对总数num,则不满足要求的数
阅读全文
摘要:【题意】两列n个火柴,分别有高度ai和bi(同一列高度互不相同),每次可以交换一列中的两个相邻火柴,定义距离为∑(ai-bi)^2,求使距离最小的最少交换次数,n<=10^5。 【算法】逆序对 【题解】∑(ai-bi)^2=∑ai^2+∑bi^2-∑ai*bi,其中∑ai^2和∑bi^2为常数,则要
阅读全文
摘要:【题目】洛谷10月月赛R1 提高组 【算法】递推DP+树状数组 【题解】列出DP递推方程,然后用树状数组维护前后缀和。 #include<cstdio> #include<cstring> #include<cctype> #include<cmath> #include<algorithm> #d
阅读全文
摘要:【算法】线段树||树状数组&&并查集 【题解】修改必须暴力单点修改,然后利用标记区间查询。 优化:一个数经过不断开方很快就会变成1,所以维护区间最大值。 修改时访问到的子树最大值<=1时,该区间就不必修改。 #include<cstdio> #include<cmath> #include<algo
阅读全文
摘要:【算法】数学+线段树/树状数组 【题解】 首先三个操作可以理解为更相减损术或者辗转相除法(待证明),所以就是求区间gcd。 这题的问题在线段树维护gcd只能支持修改成一个数,不支持加一个数。 套路:gcd(a,b,c,d,e)=gcd(a-b,b-c,c-d,d-e,e),也就是所有数的gcd可以转
阅读全文
摘要:【算法】主席树||离线+树状数组 【题解】 主席树经典应用:找区间不同的数字个数。 做法:记录每个数上一次出现的位置last[i],对last建权值线段树,对于区间询问last[i]<L的数字个数。 注意权值范围是last[i],也即0~n。 注意x=0时返回,否则可能c<0就完了。 #includ
阅读全文
摘要:【算法】DFS序+树状数组 【题解】题意相当于统计前i-1个点在第i个点的祖先的个数,显然可以用dfs维护,用树状数组差分维护前缀和。 出栈不新加节点就要注意左闭右开,即in[a[i]]处+1,ou[a[i]]+1处-1。 出栈新加节点就要注意数组开双倍。 #include<cstdio> #inc
阅读全文
摘要:【题意】带修改的查询区间第k小 【算法】树状数组套可持久化线段树 【题解】对于树状数组上的每个节点,维护可持久化权值线段树(节点为权值),从而达到查询前缀和的目的。 对于每次修改,在待修改线段树基础上运用可持久化性质来修改,先删除原数字,再加入新数字。 注意记录修改后的原数字,方便后来删除。 ★注意
阅读全文
摘要:【关键字】偏序,数点,树状数组,线段树,扫描线。 因为涉及多种算法,所以整合到一起。 【扫描线】 二维数点,偏序 ★数点问题 ★关于偏序问题的一些总结 扫描线是一维离线的做法的统称,常用于解决k维偏序问题。 离线:将其中一维的询问排序后按顺序处理,从而实现按时间顺序处理的过程中可以O(1)统计空间上
阅读全文
摘要:【算法】扫描线:差分+树状数组 【题意】转化模型后:求每个矩形覆盖多少点和每个点被多少矩形覆盖。n<=10^5。 【题解】经典的扫描线问题(二维偏序,二维数点)。 数点问题 将所有询问离线并离散化,然后按从上到下排序。 对于点被覆盖问题: 扫描线从上到下进行,遇到矩阵上边界维护区间加,遇到矩阵下边界
阅读全文
摘要:【第一题】 题意: 给一个 01 串设为其 S,询问是否存在只出现两次的 01 串 T。 这里的出现定义为存在一串下标 ,满足 且 。 2≤n≤5000,数据随机。 题解: 很容易想到部分分算法DFS枚举子集。 由于数据随机,n>10时大概率存在,直接输出。 #include<cstdio> #in
阅读全文
摘要:【题意】n个数,每个数有附加属性0或1,初始全为1。m个操作,每个操作可以改变一个数字的属性为0或1。对于每次操作后的序列求有多少子序列满足要求:5个数字,中间3个数相等且属性为1,左右两个数小于等于中间三个数且属性任意。n,m<=10^5。 【算法】线段树 【题解】朴素的算法,奇妙的使用>_<!
阅读全文
摘要:【算法】树状数组(区间和) 【题解】记得开long long #include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&(-x)) using namespace std; const int maxn=5
阅读全文