题目描述
给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数。
输入
第一行两个数N,Q,表示矩阵大小和询问组数; 接下来N行N列一共N*N个数,表示这个矩阵; 再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。
输出
对于每组询问输出第K小的数。
样例输入
2 2 2 1 3 4 1 2 1 2 1 1 1 2 2 3
样例输出
1 3
提示
矩阵中数字是109以内的非负整数;
20%的数据:N<=100,Q<=1000;40%的数据:N<=300,Q<=10000;60%的数据:N<=400,Q<=30000;100%的数据:N<=500,Q<=60000。
考虑暴力,对于每次询问二分答案,求权值$\le mid$的点的个数是否有$k$个,显然时间复杂度爆炸。
我们将所有询问一起二分,也就是整体二分。
先将每个点的权值排序,每次将权值$\le mid$的点加入到矩阵中,然后对当前要处理的所有询问进行查询。
如果查询矩形内点个数大于等于$k$那么说明这个询问的答案要在$[l,mid]$中,就将这个询问归为左区间,否则将询问的$k$减掉这次查询的结果,归为右区间。这样递归下去即可得到每个询问的答案。
至于查询矩形内点数用二维树状数组差分一下即可。
每层处理完不要忘记把树状数组清空。
#include#include