CF2143F
xujindong_ · · 题解
询问中位置
考虑固定左端点后,右端点线性基的变化次数是
枚举每一段,设上一个数是
#include<bits/stdc++.h>
using namespace std;
int t,n,m,a[200005],r[200005];
template<typename T,int maxn>struct basis{
T b[maxn];
int cnt;
basis(){
memset(b,0,sizeof(b)),cnt=0;
}
bool insert(T k){
if(cnt==maxn)return 0;
for(int i=maxn-1;i>=0;i--){
if(k>>i&1){
if(!b[i])return b[i]=k,cnt++,1;
k^=b[i];
}
}
return 0;
}
T query(int k,T ans=0){
if(k>=1<<maxn)return 1<<cnt;
for(int i=maxn-1,now=0,num=cnt;i>=0;i--){
if(b[i])num--;
if(k>>i&1){
if(~now>>i&1){
ans+=1<<num;
if(b[i])now^=b[i];
else return ans;
}
else if(b[i])ans+=1<<num;
}
else{
if(now>>i&1){
if(b[i])now^=b[i];
else return ans;
}
}
}
return ans;
}
T kth(int k){
T now=0;
for(int i=maxn-1,num=cnt;i>=0;i--){
if(!b[i])continue;
num--;
if(k<=1<<num){
if(now>>i&1)now^=b[i];
}
else{
k-=1<<num;
if(~now>>i&1)now^=b[i];
}
}
return now;
}
};
int main(){
ios::sync_with_stdio(0),cin.tie(0),cin>>t;
while(t--){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
vector<int>p(1,n+1);
for(int i=n;i>=1;i--){
vector<int>nxt(1,i);
basis<int,20>b;
b.insert(a[i]);
for(int j=0;j<p.size()-1;j++)if(b.insert(a[p[j]]))nxt.push_back(p[j]);
nxt.push_back(n+1),p=nxt,b=basis<int,20>(),b.insert(a[i]);
for(int j=1,v=0;j<p.size();j++){
int num=b.query(v);
if((1<<b.cnt)-num<p[j]-p[j-1]){
r[i]=p[j-1]+(1<<b.cnt)-num-1;
break;
}
else r[i]=p[j]-1,v=b.kth(num+p[j]-p[j-1])+1;
b.insert(a[p[j]]);
}
}
for(int i=1,x,y;i<=m;i++)cin>>x>>y,puts(r[x]>=y?"Yes":"No");
}
return 0;
}