区间and和区间or模版

区间的与运算和区间的或运算

1、可以求解 \(l\&(l+1)...\&r\) 或者 \(l|(l+1)...|r\) 的值,\(1\le l\le r\le 1e18\)

2、时间复杂度 \(logn\) 的级别。

struct Or_And{
	i64 c;
	i64 f[65][65][2];
	vector<i64> nums;
	Or_And() : nums(66, 0) {
		for (int i = 0; i <= 64; i++)
			for (int j = 0; j <= 64; j++)
				for (int k = 0; k <= 1; k++)
					f[i][j][k] = -1;
		c = 0;
	}
	
	i64 dp(bool islimit, i64 m, i64 sum, i64 num) {
		if (!islimit && ~f[m][num][sum]) {
			return f[m][num][sum];
		}
		
		if (!m) {
			return sum;
		}
		
		i64 ans = 0;
		for (int i = 0; i <= 1; i++) {
			if (islimit && i > nums[m]) {
				break;
			}
			
			ans += dp(islimit && nums[m] == i, m - 1, (m == num ? (i == 1 ? 1 : 0) : sum), num);
		}
		
		if (!islimit) f[m][num][sum] = ans;
		return ans;
	}
	
	i64 ask(i64 n, i64 k) {
		c = 0;
		while (n) {
			nums[++c] = n & 1;
			n >>= 1LL;
		}
		
		return dp(1ll, c, 0ll, k);
	}
	
	i64 Or(i64 l, i64 r) {
		i64 ans = r;
		for (i64 k = 63; k >= 0; k--) {
			i64 u = l >> k & 1;
			i64 v = r >> k & 1;
			if (u != v) {
				ans |= (1ll << k) - 1ll;
				break;
			}
		}
		
		return ans;
	}
	
	i64 And(i64 l, i64 r) {
		i64 ans = 0;
		for (int k = 63; k >= 0; k--) {
			i64 u = l >> k & 1;
			i64 v = r >> k & 1;
			if (u != v) {
				break;
			}
			ans |= u << k;
		}
		
		return ans;
	}
};

void solve() {
	i64 l, r;
	read(l, r);
    Or_And t;
	cout << t.Or(l, r) << '\n';
}
posted @ 2024-08-31 17:57  grape_king  阅读(27)  评论(0)    收藏  举报