题目大意:
给出n个五元组,q次询问,每次询问给出一个五元组,问n个五元组中完全小等于该五元组的有多少个。
解题思路:
很容易想到用bitset[i][j]处理出第i科前j名是那些人,询问直接二分后把5个bitset与到一次即可。
但这样空间开不下,所以分一下块,bitset[i][j]表示第i科前j块是哪些人,询问是单独处理边界上的人即可。
#include<bits/stdc++.h>
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=50005,INF=0x3f3f3f3f;
struct node{int id,val;}a[6][N];
inline bool operator < (const node &a,const node &b)
{return a.val<b.val;}
int T,n,m,S,lastans;
bitset<N>b[6][250],f,ans;
int main()
{
//freopen("lx.in","r",stdin);
T=getint();
while(T--)
{
n=getint(),m=getint(),S=sqrt(n),lastans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=5;j++)
a[j][i].id=i,a[j][i].val=getint();
for(int j=1;j<=5;j++)sort(a[j]+1,a[j]+n+1),a[j][n+1].val=INF;
for(int j=1;j<=5;j++)
{
f.reset();
for(int i=1;i<=n;i++)
{
f[a[j][i].id]=1;
if(i%S==0||i==n)b[j][(i-1)/S+1]=f;
}
}
m=getint();
while(m--)
{
ans.set();
for(int j=1;j<=5;j++)
{
node x;x.val=getint()^lastans;
int p=upper_bound(a[j]+1,a[j]+n+1,x)-a[j]-1;
int lS=p/S;f=b[j][lS];
for(int i=lS*S+1;i<=p;i++)f[a[j][i].id]=1;
ans&=f;
}
printf("%d\n",lastans=ans.count());
}
}
return 0;
}