1 /*
2 题意:五维偏序,n<=50000,有n个五元组,Q个询问,对于每个询问五元组,查询有多少个小于等于该询问的五元组
3 题解:分块,对于每一维,利用bitset维护一个分块,表示在当前位置之前,小于等于当前位置的状态,不同分块状态之间的转移应包括原有的状态,加上当前分块的情况
4 对于每个询问,二分小于每一维的位置,前缀部分可用分块的信息,然后暴力剩下的部分。最终的结果是五个维之间的与。
5 时间:2018.07.19
6 */
7
8 #include <bits/stdc++.h>
9 using namespace std;
10
11 typedef long long LL;
12 const int MAXN = 50005;
13 const LL MOD7 = 1e9+7;
14
15 inline int read()
16 {
17 int x=0,f=1;char c=getchar();
18 while (c<'0' || c>'9') {c=='-' && (f=-1);c=getchar();}
19 while (c>='0' && c<='9') {x=x*10+c-'0',c=getchar();}
20 return x*f;
21 }
22
23 struct Node
24 {
25 int x,y;
26 }a[7][50005];
27
28 int cmp(Node ca,Node cb)
29 {
30 return ca.x<cb.x;
31 }
32
33 int belong[MAXN],l[MAXN],r[MAXN],qsize,num;
34 bitset<50005> b[7][500];
35 bitset<50005> Ans[7];
36 int n,Q,m;
37
38 void build()
39 {
40 qsize = sqrt(n);
41 num = qsize;
42 if (num*num<n) ++num;
43 for (int i=1;i<num;++i)
44 {
45 l[i]=(i-1)*qsize+1;
46 r[i]=i*qsize;
47 for (int j=l[i];j<=r[i];++j) belong[j]=i;
48 }
49 l[num]=(num-1)*qsize+1;
50 r[num]=n;
51 for (int j=l[num];j<=r[num];++j) belong[j]=num;
52 }
53
54
55 int main()
56 {
57 #ifndef ONLINE_JUDGE
58 freopen("test.txt","r",stdin);
59 #endif // ONLINE_JUDGE
60 int Case;
61 scanf("%d",&Case);
62 while (Case--)
63 {
64 n=read(),m=read();
65 for (int i=1;i<=n;++i)
66 {
67 for (int j=1;j<=5;++j)
68 {
69 a[j][i].x=read();
70 a[j][i].y=i;
71 }
72 }
73 build();
74 for (int i=0;i<=num;++i)
75 {
76 for (int j=1;j<=5;++j)
77 {
78 b[j][i].reset();
79 }
80 }
81 for (int j=1;j<=5;++j)
82 {
83 sort(a[j]+1,a[j]+1+n,cmp);
84 for (int i=1;i<=num;++i)
85 {
86 b[j][i]|=b[j][i-1];
87 for (int k=l[i];k<=r[i];++k)
88 b[j][i][a[j][k].y]=1;
89 }
90 }
91
92 Q=read();
93 int now[7];
94 int ans=0;
95 for (int i=1;i<=Q;++i)
96 {
97 for (int j=1;j<=5;++j)
98 {
99 now[j]=read();
100 if (i!=1) now[j]^=ans;
101 Ans[j].reset();
102 }
103 for (int j=1;j<=5;++j)
104 {
105 // int p = a[j]+1+n - upper_bound(a[j]+1, a[j]+1+n, now[j]);
106 int L=1,R=n;
107 int mid;
108 while (L<=R)
109 {
110 mid =(L+R)/2;
111 // printf("L=%d R=%d mid=%d a[%d][%d].x=%d now[%d]=%d\n", L,R,mid,j,mid,a[j][mid].x,j,now[j]);
112 if (a[j][mid].x<=now[j]) L=mid+1;
113 else R=mid-1;
114 }
115 int p=L-1;
116 // printf("p=%d\n",p);
117 Ans[j] |= b[j][belong[p]-1];
118 for (int k=l[belong[p]];k<=p;++k)
119 Ans[j][a[j][k].y]=1;
120 }
121 Ans[1]=Ans[1]&Ans[2]&Ans[3]&Ans[4]&Ans[5];
122 ans = Ans[1].count();
123 printf("%d\n",ans);
124 }
125 }
126 return 0;
127 }