E. Distance Learning Courses in MAC
time limit per test 2 seconds
memory limit per test 256 megabytes
input standard input
output standard output
The New Year has arrived in the Master's Assistance Center, which means it's time to introduce a new feature!
Now students are given distance learning courses, with a total of n n n courses available. For the i i i-th distance learning course, a student can receive a grade ranging from x i x_i xi to y i y_i yi.
However, not all courses may be available to each student. Specifically, the j j j-th student is only given courses with numbers from l j l_j lj to r j r_j rj, meaning the distance learning courses with numbers l j , l j + 1 , ... , r j l_j,l_{j+1},...,r_j lj,lj+1,...,rj.
The creators of the distance learning courses have decided to determine the final grade in a special way. Let the j j j-th student receive grades c l j , c l j + 1 , ... , c r j c_{l_j},c_{l_{j+1}},...,c_{r_j} clj,clj+1,...,crj for their distance learning courses. Then their final grade will be equal to c l j ∣ c l j + 1 ∣ ... ∣ c r j c_{l_j} |\ c_{l_{j+1}} |\ ...\ | c_{r_j} clj∣ clj+1∣ ... ∣crj, where | denotes the bitwise OR operation.
Since the chatbot for solving distance learning courses is broken, the
students have asked for your help. For each of the q q q students, tell them the maximum final grade they can achieve.
Input
Each test consists of multiple test cases. The first line contains a single integer t ( 1 ≤ t ≤ 2 ⋅ 1 0 4 ) t (1\le t\le 2⋅10^4) t(1≤t≤2⋅104) --- the number of test cases. The description of the test cases follows.
The first line of each test case contains a single integer n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n (1\le n\le 2⋅10^5) n(1≤n≤2⋅105) --- the number of distance learning courses.
Each of the following n n n lines contains two integers x i x_i xi and y i y_i yi ( 0 ≤ x i ≤ y i < 2 30 ) (0\le x_i\le y_i\lt2^{30}) (0≤xi≤yi<230) --- the minimum and maximum grade that can be received for the i i i-th course.
The next line contains a single integer q ( 1 ≤ q ≤ 2 ⋅ 1 0 5 ) q (1\le q\le2⋅10^5) q(1≤q≤2⋅105) --- the number of students.
Each of the following q q q lines contains two integers l j l_j lj and r j r_j rj ( 1 ≤ l j ≤ r j ≤ n ) (1\le l_j\le r_j\le n) (1≤lj≤rj≤n) --- the minimum and maximum course numbers accessible to the j j j-th student.
It is guaranteed that the sum of n n n over all test cases and the sum of q q q over all test cases do not exceed 2 ⋅ 1 0 5 2⋅10^5 2⋅105.
Output
For each test case, output q q q integers, where the j j j-th integer is the maximum final grade that the j j j-th student can achieve.
Example
input
3
2
0 1
3 4
3
1 1
1 2
2 2
4
1 7
1 7
3 10
2 2
5
1 3
3 4
2 3
1 4
1 2
6
1 2
2 2
0 1
1 1
3 3
0 0
4
3 4
5 5
2 5
1 2
output
1 5 4
15 11 15 15 7
1 3 3 3
思路:按二进制位从高到低计算,假设所有 x i = 0 x_i=0 xi=0,此时只需考虑 y i y_i yi的上限,设 c c c为二进制第 k k k为 1 1 1的 y i y_i yi个数,则有
- c = 0 c=0 c=0,没有任何一个数第 k k k位为1,答案不变。
- c = 1 c=1 c=1,只有一个数第 k k k位为1,则答案加上 2 k 2^k 2k。
- c > 1 c>1 c>1,至少有2个数第 k k k位为1,因为下限 x i = 0 x_i=0 xi=0,所以我们可以将其中一个数的第 k k k位置为0,剩下的 k − 1 k-1 k−1位全置为1,即 2 k 2^k 2k变为 2 k − 1 2^k-1 2k−1,另一个数不变,则答案可以加上 2 k + ( 2 k − 1 ) 2^k+(2^k-1) 2k+(2k−1),则此时答案剩下的 k k k位已经全部变为1了,无需再向低位统计了。
所以我们只要去掉 x i x_i xi的限制,就可以利用前缀和统计每个二进制位1的个数,并根据上面规则算出最大答案。
如何去掉 x i x_i xi的限制呢,统计每对 ( x i , y i ) (x_i,y_i) (xi,yi)从高位到低位二进制的最长公共前缀值记为 w i w_i wi,并将 w i w_i wi从 ( x i , y i ) (x_i,y_i) (xi,yi)中减去变为 ( x i − w i , y i − w i ) (x_i-w_i,y_i-w_i) (xi−wi,yi−wi)即 ( x i ′ , y i ′ ) (x_i',y_i') (xi′,yi′),则此时就无需考虑 x i x_i xi的限制了,因为我们将 w i w_i wi从 ( x i , y i ) (x_i,y_i) (xi,yi)中减去以后,此时 y i ′ y_i' yi′最高位为 1 1 1, x i ′ x_i' xi′对应的最高位必为 0 0 0( y i ′ ≥ x i ′ + 1 y_i'\ge x_i'+1 yi′≥xi′+1),所以无论我们将 y i ′ y_i' yi′中的任何为 1 1 1的第 k k k位置为0,剩下的 k − 1 k-1 k−1位置为1,都能保证 y i ′ ≥ x i ′ y_i'\ge x_i' yi′≥xi′。
cpp
#include<bits/stdc++.h>
#define lson (k<<1)
#define rson (k<<1)+1
#define mid ((l+r)/2)
#define sz(x) int(x.size())
#define pii pair<ll,ll>
#define fi first
#define se second
using namespace std;
const int MAX=2e5+10;
const int MOD=998244353;
const int INF=1e9;
const double PI=acos(-1.0);
const double eps=1e-9;
typedef int64_t ll;
int s[30][MAX];
int c[30][MAX];
int solve()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
for(int j=29;j>=0;j--)
{
s[j][i]=s[j][i-1];
c[j][i]=c[j][i-1];
if((y&(1<<j))==0)continue;
if(x<((y>>j)<<j))c[j][i]++;
else s[j][i]++;
}
}
int q;
scanf("%d",&q);
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
int ans=0;
for(int i=29;i>=0;i--)
{
int cnt=c[i][y]-c[i][x-1]+(s[i][y]-s[i][x-1]>0);
if(cnt==1)ans|=1<<i;
if(cnt>1)
{
ans|=(2<<i)-1;
break;
}
}
printf("%d ",ans);
}
return puts("");
}
int main()
{
int T;
cin>>T;
while(T--)solve();
return 0;
}