LINK:WD与数列 这道题可谓妙绝 我明白了一个增量统计的原理. 原本的想法是:差分之后 显然长度为1的单独统计 长度为2的以及更多就是字符串之间的匹配问题了. 对差分序列建立SAM 由于第一个是一定匹配的 且后面的大小关系相同 所以可以直接取差分后的来建立SAM. 考虑计算答案 容易想到对于某个节点单独统计答案 那就是right集合上len暴力扫了 可能可以通过45分 我没试过 且这个暴力过于暴力 也不好说明复杂度. 考虑一件事情 其实统计答案的本质是 len.right集合中x,y三者之间…
题目大意 给你一个字符串,求有多少对不相交且相同的子串. 位置不同算多对. \(n\leq 300000\) 题解 先把后缀树建出来. DFS 整棵树,维护当前子树的 right 集合. 合并两个集合的时候暴力枚举小的那个集合,然后在另一个集合的线段树中查询相应的信息计算贡献. 怎么计算呢? 如果两个位置之差 \(>\) 这两个位置的 \(lcp\)(即当前点的深度),那么贡献就是 \(lcp\),否则是位置之差. 线段树记录区间点数和位置之和即可. 时间复杂度:\(O(n\log^2n)\),…
传送门 解题思路 区间加等差数列+单点询问,用差分+线段树解决,线段树里维护的就是差分数组,区间加等差数列相当于在差分序列中l位置处+首项的值,r+1位置处-末项的值,中间加公差的值,然后单点询问就相当于在差分数列中求前缀和. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; ; typedef long long LL;…
题意:支持合并,求块内K小数 对于 100%的数据 n≤100000,m≤n,q≤300000 思路:对于每一个块建立一棵动态开点的线段树,暴力(启发式?)合并后二分下就行了 merge用函数的方式写因为懒得讨论x,y其中一个为0的情况,反正是把节点y并到x上 为什么这么暴力都不T?大概是因为随机数据的块的大小太平均了吧 ..,..]of longint; sum:..]of longint; fa,a,root:..]of longint; n,m,x,y,k,i,j,s,cnt,p,q:lo…
传送门 : COGS 2638. 数列操作ψ 线段树 这道题让我们维护区间最大值,以及维护区间and,or一个数 我们考虑用线段树进行维护,这时候我们就要用到吉司机线段树啦 QAQ 由于发现若干次and,or之后,如果数据分布均匀,那么几乎所有的数在若干次操作后都会变成同一个数 因为我们的and操作中的0位,以及or操作当中的1位,都是可以把整个区间的那一二进制位重置为相同的 我们考虑利用这一个性质 如果我们直接维护一个区间内的值是否是相同的,那么效果会差很多. 我们发现我们在进行and操作的时…
BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知 道N次操作后数列中所有元素的和.他还要玩其他游戏,所以这个问题留给你解决. Input 第一行一个整数N,然后有N行,每行三个正整数a.b.k. N<=40000 , a.b.k<=10^9 Output 一个数,数列中所有元素的和 Sampl…
复习SAM板子啦!考前刷水有益身心健康当然这不是板子题/水题…… 很容易发现只在i位置出现的串一定是个前缀串.那么对答案的贡献分成两部分:一部分是len[x]-fa~len[x]的这部分贡献会是r-l+1:剩下一部分1~len-fa-1这部分会和i~r构成答案,写两棵线段树即可. 然后就又是板子题了,两个板子(SAM+线段树)套起来. #include<bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt&l…
解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分出这个位置上的数是多少,然后将所有小于等于的数全部赋为0,其余赋为1,这样每次排序都是01序列排序了.如果最后p位置上的数为0则说明最终答案小于等于当前二分的答案,反之亦然. 这样这个问题就在$O(n \log^2 n)$的复杂度内解决了. #include<cstdio> #include<…
An easy problem B Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Problem Description N个数排成一列,每个数的大小为1或者0.有两种操作,第一种操作是把一段区间内的每个数异或1,第二种操作是询问区间内最长连续1的长度. Input 第一行一个整数N(1≤N≤100000),表示N个数.第二行N个数.接下来一行一个整数M(1≤M≤100000),表示…
这俩东西听起来很高端,实际上很好写,应用也很多~ 线段树合并 线段树合并,顾名思义,就是建立一棵新的线段树保存原有的两颗线段树的信息. 考虑如何合并,对于一个结点,如果两颗线段树都有此位置的结点,则直接合并两结点的信息(如维护最大值则取max,维护和则相加),然后递归处理左右子树: 若只有一个有,直接返回即可. 这样子做时间复杂度取决于重合节点个数,一次最坏复杂度是$O(nlogn)$,因为满二叉树的结点数是$O(n)$,对每个结点进行处理是$O(logn)$,但是实际应用中需要合并的两颗树重合…