Description

  给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数。

Input

  第一行两个数N,Q,表示矩阵大小和询问组数;
  接下来N行N列一共N*N个数,表示这个矩阵;
  再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。

Output

  对于每组询问输出第K小的数。

Sample Input

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

Sample Output

1
3

HINT

矩阵中数字是10^9以内的非负整数;

20%的数据:N<=100,Q<=1000;

40%的数据:N<=300,Q<=10000;

60%的数据:N<=400,Q<=30000;

100%的数据:N<=500,Q<=60000。

我们可以整体二分,这样可以转换成对于每个矩形计算其内部有多少点。

扫描线+树状数组就可以了,时间复杂度O(Nlog^2N)。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=<<;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=,f=;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-;
for(;isdigit(c);c=Getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
const int maxm=;
const int maxc=;
struct Array {
int x,y,val;
bool operator < (const Array& ths) const {return val<ths.val;}
}A[maxn];
struct Query {
int x,y,l,r,k,id;
}q[maxm];
int n,m,r,Q[maxm],tmp[maxm],ans[maxm];
struct Point {
int x,y;
bool operator < (const Point& ths) const {return x<ths.x;}
}P[maxn];
int res[maxm];
struct Rect {
int x,l,r,tp,id;
bool operator < (const Rect& ths) const {return x<ths.x;}
}B[maxm<<];
int sumv[maxc],cur[maxc],clo;
int query(int x) {
int res=;
for(;x;x-=x&-x) if(cur[x]==clo) res+=sumv[x];
return res;
}
void add(int x,int v) {
for(;x<=r;x+=x&-x)
if(cur[x]==clo) sumv[x]+=v;
else cur[x]=clo,sumv[x]=v;
}
void solve(int l,int r,int h,int t) {
if(h>t) return;
if(l==r) {
rep(i,h,t) ans[q[Q[i]].id]=A[l].val;
return;
}
int mid=l+r>>,m1=,m2=;
rep(i,l,mid) P[++m1]=(Point){A[i].x,A[i].y};
rep(i,h,t) {
res[i]=;
B[++m2]=(Rect){q[Q[i]].x-,q[Q[i]].l,q[Q[i]].r,-,i};
B[++m2]=(Rect){q[Q[i]].y,q[Q[i]].l,q[Q[i]].r,,i};
}
sort(P+,P+m1+);sort(B+,B+m2+);int j=;clo++;
rep(i,,m2) {
while(j<=m1&&P[j].x<=B[i].x) add(P[j].y,),j++;
res[B[i].id]+=B[i].tp*(query(B[i].r)-query(B[i].l-));
}
int L=h,R=t;
rep(i,h,t) if(res[i]>=q[Q[i]].k) tmp[L++]=Q[i];
else q[Q[i]].k-=res[i],tmp[R--]=Q[i];
rep(i,h,t) Q[i]=tmp[i];//开始手残没有写这行话QAQ(AQ)*
solve(l,mid,h,R);solve(mid+,r,R+,t);
}
int main() {
r=read();m=read();
rep(i,,r) rep(j,,r) A[++n]=(Array){i,j,read()};
sort(A+,A+n+);
rep(i,,m) q[Q[i]=q[i].id=i].x=read(),q[i].l=read(),q[i].y=read(),q[i].r=read(),q[i].k=read();
solve(,n,,m);
rep(i,,m) printf("%d\n",ans[i]);
return ;
}

BZOJ2738: 矩阵乘法的更多相关文章

  1. [bzoj2738]矩阵乘法_整体二分_树状数组

    矩阵乘法 bzoj-2738 题目大意:给定一个$n*n$的矩阵.每次给定一个矩阵求矩阵$k$小值. 注释:$1\le n\le 500$,$1\le q\le 6\cdot 10^4$. 想法: 新 ...

  2. BZOJ2738矩阵乘法——整体二分+二维树状数组

    题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入   第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5 ...

  3. [BZOJ2738]矩阵乘法-[整体二分+树状数组]

    Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. (N<=500,Q<=60000) Solution 考虑二分答案,问题转化为求矩阵内为1 ...

  4. [BZOJ2738]矩阵乘法 整体二分+二维树状数组

    2738: 矩阵乘法 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1643  Solved: 715[Submit][Status][Discuss ...

  5. BZOJ2738: 矩阵乘法(整体二分)

    Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. Input 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N*N个数,表示这个矩阵: ...

  6. BZOJ2738 矩阵乘法 【整体二分 + BIT】

    题目链接 BZOJ2738 题解 将矩阵中的位置取出来按权值排序 直接整体二分 + 二维BIT即可 #include<algorithm> #include<iostream> ...

  7. 【分块】【链表】bzoj2738 矩阵乘法

    http://www.cnblogs.com/jianglangcaijin/p/3460012.html 首先将矩阵的数字排序.设置size,每次将size个数字插入.插入时,我们用h[i][j]记 ...

  8. bzoj2738矩阵乘法

    题意: 给你一个N*N的矩阵,没有修改,每次询问一个子矩形中的第K小数. 题目链接 思路: 当它只有一列时,其实就是区间第K大,也就是整体二分可以解决的. 现在到了二维,只需要将之前的树状数组改成二维 ...

  9. BZOJ2738 矩阵乘法(整体二分+树状数组)

    单个询问二分答案即可,多组询问直接整体二分再二维BIT.注意保证复杂度. #include<iostream> #include<cstdio> #include<cma ...

随机推荐

  1. CPU tick counter

    #define rdtscll(val) \ __asm__ __volatile__ ("rdtsc" : "=A" (val)) example #incl ...

  2. linux screen 命令详解(未验证+研究)

    一.背景 系统管理员经常需要SSH 或者telent 远程登录到Linux 服务器,经常运行一些需要很长时间才能完成的任务,比如系统备份.ftp 传输等等.通常情况下我们都是为每一个这样的任务开一个远 ...

  3. PHP中magic_quotes_gpc动态关闭无效的问题

    昨天浏览线上项目,发现了一个问题:部分文本输出中的引号前多了一道反斜杠,比如: 引号内容多了\"反斜杠\" 单从页面展现的结果来看,猜测应该是PHP中的magic_quotes_g ...

  4. 转载一篇关于ios静态库的文章

    http://blog.csdn.net/zsomsom/article/details/9163635

  5. Hadoop 2.6.0 集群部署

    Hadoop的集群部署和单节点部署类似,配置文件不同,另外需要修改网络方面的配置 首先,准备3台虚拟机,系统为CentOS 6.6,其中一台为namenode 剩余两台为 datanode: 修改主机 ...

  6. php中正则表达式的匹配和数据验证总结

    正则表达式能匹配复杂的字符串形式,比字符串处理函数功能更加多,只不过执行效率有所降低,但是可以实现非常复杂的匹配,下面总结一下 1.简单的字符串匹配,判断指定字符串是不是在另一个字符串中,和字符串查找 ...

  7. Python网络编程(4)——异步编程select & epoll

    在SocketServer模块的学习中,我们了解了多线程和多进程简单Server的实现,使用多线程.多进程技术的服务端为每一个新的client连接创建一个新的进/线程,当client数量较多时,这种技 ...

  8. 修改PHP网站默认首页

    一般默认的首页文件是index.php index.php3 index.html index.htm之类的,要想修改为myNewIndex.php, 进入服务器Apache目录,找到httpd.co ...

  9. Hadoop学习:

    文件名称 格式 描述 hadoop-env.sh BaSh 脚本 记 录 脚 本 要 用 的 环 境 变 , 以 运 行Hadoop core-site.xml HadooP配XML Hadoop C ...

  10. 工作空间项目不存在,eclipse中项目删不掉

    解决:E:\androidworkspaceall\.metadata\.plugins\org.eclipse.core.resources\.projects  ->删除对应项目