区间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';
}

浙公网安备 33010602011771号