五维偏序模板(bitset+分块)
很简单的维护一下分块就可以了
似乎也不需要多讲什么
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
return res*f;
}
const int N=1e5;
struct node{
int val,id;
node(){}
node(int _v,int _i):val(_v),id(_i){}
bool operator <(const node &a)const{
return val==a.val?id<a.id:val<a.val;
}
}a[6][N];
bitset<N>bit[6][300];
bitset<N>ans,tmp;
int n,m,q,blo,num;
int main(){
int T=read();
while(T--){
n=read(),m=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=5;j++){
a[j][i].val=read(),a[j][i].id=i;
}
}
for(int i=1;i<=5;i++)sort(a[i]+1,a[i]+n+1);
blo=sqrt(n);
for(int i=1;i<=5;i++){
for(int j=1;(j-1)*blo<n;j++){
bit[i][j].reset();
bit[i][j]=bit[i][j-1];
int now=(j-1)*blo;
for(int k=1;k<=blo&&now+k<=n;k++){
bit[i][j].set(a[i][now+k].id);
}
}
}
q=read();
int now[6],pre=0;
while(q--){
for(int i=1;i<=5;i++)now[i]=read(),now[i]^=pre;
ans.reset();
for(int i=1;i<=5;i++){
int pos=lower_bound(a[i]+1,a[i]+n+1,node(now[i],n+1))-a[i]-1;
pos/=blo;
tmp=bit[i][pos];
for(int j=pos*blo+1;a[i][j].val<=now[i]&&j<=n;j++){
tmp.set(a[i][j].id);
}
if(i==1)ans=tmp;
else ans&=tmp;
}
cout<<(pre=ans.count())<<'\n';
}
}
}