CF1090H Linearization 位运算、前缀和

位运算与差分数组优化
本文探讨了在处理特定位运算问题时,利用差分数组优化算法的策略。通过分析linear串的性质,提出了一个高效算法,能够在O(nq)的时间复杂度内解决区间取反操作下的最小化修改次数问题。文章详细解释了如何通过差分数组简化计算,并给出了实现代码。

传送门


有点神仙的题目

首先注意到对于串\(s\)\(b=s_0\)一定会比\(b = s_0 \bigoplus 1\)更优

考虑先分析linear串的性质。注意到位运算考虑按位处理。我们考虑\(x\)的最高位,如果\(x\)的最高位为\(1\),那么linear串的前后两半的异或和为\(0\),否则前后两半完全相等。那么可以得到一个重要的性质:对于一个linear的串,把其分为前半段和后半段,前半段和后半段要么相等,要么完全不同,对于前后两半段还需递归满足这个条件。

好像有这个性质也没有什么用,但是注意到每一次的修改是区间取反,这在差分数组上会体现为两个位置的修改,比较方便。所以我们考虑差分处理。我们不妨分析一下差分之后linear串的性质。设\(t_i = s_i \bigoplus s_{i-1} , i \in [1 , |s|)\)。对于差分数组\(t\),因为\(s\)的前半段和后半段相等,所以差分数组除了\(\frac{|s|}{2}\)的位置可以随意取值,剩下的由\(\frac{|s|}{2}\)分开的两个差分数组对应位置相等,且分开得到的两个差分数组还需递归满足这个性质。

我们对于给出的\(01\)串进行差分,对于一个询问\([l,r]\)只需要将\([l+1,r]\)的差分数组用尽可能少的单点取反变为一个满足linear串差分数组性质的数组。注意到linear串差分数组的性质是一些位置的值相等,我们可以把这些值拿出来,用\(\min\{cnt_0 , cnt_1\}\)贡献答案,这样可以做到\(O(nq)\)

最后需要考虑如何快速求出一个连通块内\(0/1\)个数。不难发现对于所有\(lowbit\)相等的位置会形成一个连通块(这个可以考虑所有\(lowbit\)相同的点,然后考虑自底向上时的连边情况,不难发现这些点连成一棵树且没有往外连边),然后记一下前缀和计算对于\(lowbit\)相等的所有位置的\(1\)的个数即可。

代码

转载于:https://www.cnblogs.com/Itst/p/11135227.html

### 线性化的定义与实现 线性化(Linearization)通常指将复杂的数据结构或对象转换为一维表示的过程。这种技术广泛应用于编程和数据处理领域,尤其是在涉及多维数组、树形结构或其他嵌套数据形式的情况下。 #### 多维数组的线性化 对于多维数组而言,线性化意味着将其映射到一维数组上以便于存储和访问。常见的两种方式是按照行优先顺序(Row-Major Order)或者列优先顺序(Column-Major Order)。例如,在C语言中,默认采用的是行优先顺序[^1]: ```c int matrix[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; // 将二维矩阵转化为一维数组 for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { int linear_index = i * 3 + j; printf("%d ", matrix[i][j]); } } ``` 上述代码展示了如何通过简单的数学运算来获取对应的一维索引位置。 #### 树形结构的线性化 当面对诸如二叉树这样的非线性数据结构时,可以通过遍历算法(如前序、中序或后序遍历)得到其节点序列作为线性表现形式之一。下面是一个基于Python的例子展示了一种可能的方法——利用广度优先搜索(BFS),即层次遍历来完成这一过程[^2]: ```python from collections import deque class TreeNode: def __init__(self, value=0, left=None, right=None): self.value = value self.left = left self.right = right def tree_linearization(root): result = [] queue = deque([root]) while queue: node = queue.popleft() if not node: continue result.append(node.value) queue.extend([node.left, node.right]) return result # Example usage if __name__ == "__main__": root = TreeNode(1) root.left = TreeNode(2) root.right = TreeNode(3) root.left.left = TreeNode(4) root.left.right = TreeNode(5) print(tree_linearization(root)) # Output: [1, 2, 3, 4, 5] ``` 此函数接受一棵二叉树作为输入参数,并返回该树所有结点值组成的列表,按照从左至右逐层排列的方式呈现出来。 #### 自然语言生成中的线性化 在线自然语言生成(NLG)任务里,“线性化”可以理解成把抽象语法树(AST)或者其他内部表达形式转化成语法正确的句子字符串操作的一部分流程[^4]。这一步骤至关重要,因为它直接影响最终输出的质量以及可读性等方面的表现效果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值