CF1935E 题解
sunkuangzheng · · 题解
- 给定序列
\{x_n\},\{y_n\} ,共有q 组询问,第i 组询问给出l,r ,你需要构造序列a 满足a_i \in [x_i,y_i] ,求\max \operatorname{OR}_{i=l}^r a_i 。
提示 1
考虑对于一对
提示 2
如果所有
题解
首先我们对于每一对
你也可以通过以上流程发现,在去除最长公共前缀后
可以前缀和统计出现次数,ST 表维护区间或,时间复杂度
/**
* author: sunkuangzheng
* created: 06.03.2024 07:28:11
**/
#include<bits/stdc++.h>
#ifdef DEBUG_LOCAL
#include <mydebug/debug.h>
#endif
using ll = long long;
const int N = 5e5+5;
using namespace std;
int T,n,q,x,y,l,r;
void los(){
cin >> n;
vector<vector<int>> ct(36,vector<int>(n + 1)),st(25,vector<int>(n + 1));
for(int i = 1;i <= n;i ++){
cin >> x >> y;
for(int j = 30;j >= 0;j --)
if(((x >> j) & 1) == ((y >> j) & 1)) st[0][i] |= (((x >> j) & 1) << j);
else{
for(int k = j;k >= 0;k --) if((y >> k) & 1) ct[k][i] ++;
break;
}
for(int j = 30;j >= 0;j --) ct[j][i] += ct[j][i-1];
}for(int j = 1;j <= __lg(n);j ++) for(int i = 1;i + (1 << j) - 1 <= n;i ++)
st[j][i] = st[j-1][i] | st[j-1][i + (1 << j-1)];
auto qry = [&](int l,int r){
int k = __lg(r - l + 1);
return st[k][l] | st[k][r-(1<<k)+1];
};
cin >> q;
while(q --){
cin >> l >> r;
int ans = qry(l,r),w;
for(int i = 30;i >= 0;i --)
if(w = ct[i][r] - ct[i][l-1] + ((ans >> i) & 1),w >= 2) ans |= (1 << i + 1) - 1;
else if(w) ans |= (1 << i);
cout << ans << " ";
}cout << "\n";
}int main(){
ios::sync_with_stdio(0),cin.tie(0);
for(cin >> T;T --;) los();
}