Kyle is a student of Programming Monkey Elementary School. Just as others, he is deeply concerned with his grades.

Last month, the school held an examination including five subjects, without any doubt, Kyle got a perfect score in every single subject.

There are n students took part in this examination(not including Kyle), and everyone got an integer between 1 to m as the score of one subject.

Now, looking at the grade table of these n students, Kyle wants to know how many students still did no better than him even if his scores are something else – Here, “no better” means there is no subject in which the student got strictly greater score than Kyle.

Input

There are multiple test cases.

The first line of the input contains an integer T (T <= 3) which means the number of test cases.

The first line of each test case contains two integers, n, m(n, m≤ 50,000), which are the number of students and the perfect score of each subject.

In the next n lines, each line consists of five integers, indicating a student’s scores.

Then one line follows. This line contains an integer q(q≤ 50,000) indicating the number of queries.

In the next q lines, each line contains five integers as well, representing a query. Each query indicates a set of scores, and for each query, you should figure out that if Kyle's grade is this set of scores, how many students still did no better than him. But for the sake of security, only the first query is in its original form, and other queries are encrypted. To decrypt a query, you must let each integer in the query do xor operation with the answer of last query. It's guaranteed that all the decrypted queries contain integers between 1 and 50000.

Output

For each test case, you should output q lines as the answer for all queries.

Sample Input

2
2 3
1 1 1 1 1
2 2 2 2 2
2
1 1 1 1 1
3 3 3 3 3
3 5
1 1 1 1 1
1 1 1 1 1
1 2 3 4 5
2
1 1 1 1 1
1 1 1 1 1

Sample Output

1
2
2
2

Hint

In case 1, there are two students with different scores and the scores of the first student (1, 1, 1, 1, 1) are not larger than the first query (1 1 1 1 1) in every subject, so the answer for this query is 1.

After having xor operation with the last answer 1, the second query (3,3,3,3,3) will be decrypted into (2, 2, 2, 2, 2). Because both students’ scores are no better than  (2, 2, 2, 2, 2), so the answer for query 2 is 2.


  题目大意 给定n个五元组,在给定q个五元组,询问每个5元组在偏序意义下,有多少个小于等于它。(强制在线,多组数据)

  五维偏序,根据常用套路n - 1维套树,总时间复杂度O(nlog4n)。请问这和暴力区别有多大?

  既然无法区分套树做法和暴力。那就暴力 + 黑科技卡过去吧。

  如果你认为这个暴力是每个询问直接去for套for(第二个for是比较),总时间复杂度为O(nqk)的暴力,那你没救了,赶快换道题吧。

  考虑如果每一维单独比较,然后最后把所有可行的集合取交集,这样似乎可以继续进行优化。

  每一维比较的时候可以用二分查找。既然又要取交集,那就bitset顶上吧。然而你需要对每一维排序后进行,bitset求前缀并(下标),这样你就可以顺利O(1)求出在这一维可行的集合。

  看起来查询很顺利,但是预处理不是怎么想的,首先5 * 4 * 50000 * 50000 / 32空间直接炸掉了。另外bitset赋值也不是O(1),所以时间也炸掉了。

  因此得均衡一下查询和预处理的耗时。所以想到了根号分块。

  然后随便搞就行了。总时间复杂度为(其中k为维度,这里为5)

  然后表示开始手抽每次询问给ans赋值时,一位一位地设成1,然后成功三发TLE,并且十分懵逼。

Code

 /**
* HihoCoder
* Problem#1236
* Accepted
* Time: 1696ms
* Memory: 22528k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; int opt;
typedef class Data {
public:
int w[]; friend boolean operator < (const Data& a, const Data& b) {
return a.w[opt] < b.w[opt];
}
}Data; int n, m, q;
int cs, cc;
Data ds[];
boolean endflag[];
int order[][];
bitset<> bs[][]; inline void init() {
scanf("%d%d", &n, &m);
cs = sqrt(n + 0.5);
cc = (n + cs - ) / cs;
// printf("Chunks datas: %d %d\n", cs, cc);
for(int i = ; i < n; i++) {
ds[i].w[] = i;
endflag[i] = !((i + ) % cs);
// if(endflag[i]) printf("endflag:%d\n", i);
for(int j = ; j <= ; j++)
scanf("%d", ds[i].w + j);
}
endflag[n - ] = true;
} inline void init_chunks(int k) {
opt = k;
sort(ds, ds + n);
for(int i = ; i < n; i++)
order[k][i] = ds[i].w[];
bitset<> b;
for(int j = ; j < n; j++) {
b[order[k][j]] = ;
if(endflag[j]) bs[k][j / cs] = bitset<>(b);
}
} inline void init_chunks() {
for(int i = ; i <= ; i++)
init_chunks(i);
opt = ;
sort(ds, ds + n);
} //int bitsetc = 0, cnt = 0; inline bitset<> solve(int k, int val) {
int l = , r = n - , ri;
bitset<> rt;
while(l <= r) {
// cnt++;
int mid = (l + r) >> ;
if(ds[order[k][mid]].w[k] > val) r = mid - ;
else l = mid + ;
}
if(r >= cs)
rt = bitset<>(bs[k][r / cs - ]);//, bitsetc++;
ri = r / cs * cs;
for(; ri <= r; ri++)
rt[order[k][ri]] = ;//, cnt++;
return rt;
} inline void solve() {
int lastans = ;
scanf("%d", &q);
bitset<> buf;
for(int i = ; i < n; i++)
buf[i] = ;
while(q--) {
bitset<> ans(buf);
for(int i = , x; i <= ; i++) {
scanf("%d", &x);
x ^= lastans;
// bitsetc++;
ans &= solve(i, x);
}
lastans = ans.count();
// bitsetc++;
printf("%d\n", lastans);
// fprintf(stderr, "Used:%d for uses:%d bitset uses:%d \n", bitsetc * 50001 / 32 + cnt, cnt, bitsetc);
}
} int T;
int main() {
scanf("%d", &T);
while(T--) {
init();
init_chunks();
solve();
}
// fprintf(stderr, "Time:%dms\n", clock());
return ;
}

最新文章

  1. web 打开子窗口提交数据或其他操作后 关闭子窗口且刷新父窗口实现
  2. console.log()与alert()的区别
  3. js替换指定字符串
  4. iOS开发——数据持久化Swift篇&amp;(三)SQLite3
  5. Dapper Use For Net
  6. Java并发编程:ThreadLocal
  7. 【一天一道LeetCode】#81. Search in Rotated Sorted Array II
  8. opencv imwrite保存图片花屏的问题
  9. nginx切割日志脚本
  10. JS入门经典第四章总结
  11. Lesson 22 A glass envelope
  12. 使用update可以防止并发问题(保证数据的准确性),如果使用select会产生并发问题 ; select * from xx for update 给查询开启事务,默认情况下是没有事物的
  13. 【python小练】0010
  14. [JDBC]你真的会正确关闭connection吗?
  15. Qt5获取本机网络信息
  16. 数据库使用SSIS进行数据清洗教程
  17. Windows系统80端口被占用
  18. vulcanjs 简单package 编写
  19. ABAP-语音输出
  20. Java入门:基础算法之产生随机数

热门文章

  1. VScode编辑器个性化配置
  2. tortoise svn中更改用户
  3. OpenCV resources
  4. Rpgmakermv(18)GALV RollCredits
  5. DataRow 点不出 Select
  6. Yii Restful api自定义字段
  7. uva 10163 Storage Keepers
  8. QT 继承QWidget &amp;&amp; 继承QDialog
  9. highcharts插件
  10. 初探AngularJs框架(二)