树状数组

单点修改,区间查询

inline void add(int u, int x) {
	for (int i = u; i <= lim[id]; i += i & -i) C[i] += x;
}
inline int get(int u) {
	int ret = 0;
	for (int i = u; i > 0; i -= i & -i) ret += C[i];
	return ret;
}

求重1开始区间和为s的下标

inline int get_lower_bound(int s) {
	int ret = 0;
	for (int i = 31 - __builtin_clz(n); i >= 0; i--) {
		ret ^= 1<<i;
		if (ret > n) { //n是最大范围
			ret ^= 1<<i;
			continue;
		}
		s -= C[ret];
		if (s <= 0) {
			s += C[ret];
			ret ^= 1<<i;
		}
	}
	return ++ret;
}
posted @ 2020-07-22 22:46  Grisaia  阅读(64)  评论(0)    收藏  举报