推广一波树状数组的 O(1) 清空
  • 板块学术版
  • 楼主HopingSeeker
  • 当前回复14
  • 已保存回复14
  • 发布时间2021/7/11 20:30
  • 上次更新2023/11/4 15:04:14
查看原帖
推广一波树状数组的 O(1) 清空
126202
HopingSeeker楼主2021/7/11 20:30

知道的大佬应该不少,可是看了看一些主要是学习新知识点的题目的用户的提交记录(主要是 cdq 分治、整体二分之类),清空树状数组主要是在操作完成之后按照题目中给定的修改改回来。

其实只需要在 bit 中加上这样一处改进,就可以做到 O(1)O(1) 清空:

实现方法就是类似于线段树的懒标记:在 bit 开一个表示每个位置版本的数组,再维护一个 bit 的总版本,每当访问到某个位置的时候,就判断一下是否与总版本不同,不同就先清空。

清空整个 bit 时只需要修改一下总版本的值即可。具体实现可以看如下的代码片段:

struct BIT {
	int array[Maxn], data_range;
	int tim[Maxn], Tim;
	BIT() {Tim = 0;}
	void modify(int x, int d) {
		while(x <= data_range) {
			if(tim[x] ^ Tim) tim[x] = Tim, array[x] = 0;
			array[x] += d; x += (-x & x);
		}
	}
	int query(int x) {
		int res = 0;
		while(x) {
			if(tim[x] ^ Tim) tim[x] = Tim, array[x] = 0;
			res += array[x]; x -= (-x & x);
		}
		return res;
	}
	void clear() {Tim++;}
} bit;

其实除了 bit 之外很多别的 ds 也能这么清空,如果本来不知道的话希望对您有所帮助。

小丑竟是我自己预定

2021/7/11 20:30
加载中...