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

  矩阵中数字是109以内的非负整数;

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

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

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

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

解题思路:

整体二分思想非常浓。

将点权排序,二分mid时加入前mid个答案。

在二维树状数组上+1

最后二维树状数组查询前缀合就知道区间有多少个数。

最后统计答案就好了。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
struct data{
int i,j;
int val;
}d[];
struct que{
int px,py,qx,qy;
int no;
int val;
}q[],ss[],sp[];
int line[][];
int n,Q;
int cnt;
int top;
int ans[];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int y,int v)
{
for(int i=x;i<=n;i+=lowbit(i))
{
for(int j=y;j<=n;j+=lowbit(j))
{
line[i][j]+=v;
}
}
return ;
}
int query(int x,int y)
{
int ans=;
for(int i=x;i;i-=lowbit(i))
{
for(int j=y;j;j-=lowbit(j))
{
ans+=line[i][j];
}
}
return ans;
}
bool cmp(data x,data y)
{
return x.val<y.val;
}
void Insert(int no,int dir)
{
update(d[no].i,d[no].j,dir);
return ;
}
int sum(int no)
{
int ret=;
ret=query(q[no].qx,q[no].qy)+query(q[no].px-,q[no].py-);
ret-=query(q[no].qx,q[no].py-)+query(q[no].px-,q[no].qy);
return ret;
}
void macrs(int l,int r,int ll,int rr)
{
if(ll>rr)
return ;
if(l==r)
{
for(int i=ll;i<=rr;i++)
ans[q[i].no]=d[l].val;
return ;
}
int mid=(l+r)>>;
while(top<mid)
Insert(++top,);
while(top>mid)
Insert(top--,-);
int sta1=,sta2=;
for(int i=ll;i<=rr;i++)
{
if(sum(i)>=q[i].val)
sp[++sta1]=q[i];
else
ss[++sta2]=q[i];
}
int sta=ll-,lmid;
for(int i=;i<=sta1;i++)
q[++sta]=sp[i];
lmid=sta;
for(int i=;i<=sta2;i++)
q[++sta]=ss[i];
macrs(l,mid,ll,lmid);
macrs(mid+,r,lmid+,rr);
return ;
}
int main()
{
scanf("%d%d",&n,&Q);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
int tmp;
scanf("%d",&tmp);
d[++cnt]=(data){i,j,tmp};
}
std::sort(d+,d+cnt+,cmp);
for(int i=;i<=Q;i++)
{
scanf("%d%d%d%d%d",&q[i].px,&q[i].py,&q[i].qx,&q[i].qy,&q[i].val);
if(q[i].px>q[i].qx)
std::swap(q[i].px,q[i].qx);
if(q[i].py>q[i].qy)
std::swap(q[i].py,q[i].qy);
q[i].no=i;
}
macrs(,cnt,,Q);
for(int i=;i<=Q;i++)
printf("%d\n",ans[i]);
return ;
}

BZOJ2738: 矩阵乘法(整体二分)的更多相关文章

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

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

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

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

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

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

  4. 【BZOJ2738】矩阵乘法 整体二分

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

  5. 【BZOJ2738】矩阵乘法 [整体二分][树状数组]

    矩阵乘法 Time Limit: 20 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 给你一个N*N的矩阵,不用算矩阵乘 ...

  6. 【bzoj2738】矩阵乘法 整体二分+二维树状数组

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

  7. BZOJ 2738: 矩阵乘法 [整体二分]

    给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 愚蠢的名字...... 整体二分,影响因子就是矩阵里的数 把$\le mid$的矩阵元素加到二维树状数组里然后询问分成两组就行 ...

  8. 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]

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

  9. BZOJ.2738.矩阵乘法(整体二分 二维树状数组)

    题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...

随机推荐

  1. [Teamcenter 2007 开发实战] 调用web service

    前言 在TC的服务端开发中, 能够使用gsoap 来调用web service. 怎样使用 gsoap  , 參考 gsoap 实现 C/C++ 调用web service 接下来介绍怎样在TC中进行 ...

  2. PostgreSQL数据库创建/删除

    方法1 - 系统命令 sudo su - postgres #切换到postgres用户(系统用户) createdb weichen #创建数据库 psql #直接訪问数据库(默认进入本地postg ...

  3. thinkphp跨模块调用

    thinkphp跨模块调用 跨模块调用模板 return $view->fetch('admin@user/add'); 全路径模板调用: return $view->fetch(APP_ ...

  4. 2.CString转换到char*

    多字节模式下: CString -->char * CString str1 ="; char *t1 =str1.GetBuffer(str1.GetLength()); str1. ...

  5. BZOJ 1193 搜索+贪心

    预处理出100*100以内的最优解 贪心走日 判断是0*4还是2*4 搞定 //By SiriusRen #include <queue> #include <cstdio> ...

  6. openSUSE Leap与 SELS的区别

    openSUSE Leap 是 openSUSE 常规发行版本的新名称,在 13.2 之前它仅仅被称为“openSUSE”. 一.openSUSE 发行周期:(15年以前仅有一个openSUSE发行版 ...

  7. XT800 在域环境在运行设置

    测试时先将防火墙关了,不然无法远程,找个问题后再打开防火墙 0. 防火墙中建立规则,允许XT800通过. 1.在客户端当前用户下运行XT800安装程序 2.输入管理员账号及密码 3.安装时选择D或E盘 ...

  8. R学习:《机器学习与数据科学基于R的统计学习方法》中文PDF+代码

    当前,机器学习和数据科学都是很重要和热门的相关学科,需要深入地研究学习才能精通. <机器学习与数据科学基于R的统计学习方法>试图指导读者掌握如何完成涉及机器学习的数据科学项目.为数据科学家 ...

  9. Mark Sweep GC

    目录 标记清除算法 标记阶段 深度优先于广度优先 清除阶段 分配 First-fit.Best-fit.Worst-fit三种分配策略 合并 优点 实现简单 与保守式GC算法兼容 缺点 碎片化 分配速 ...

  10. 洛谷 P1985 翻转棋

    P1985 翻转棋 题目描述 农夫约翰知道,聪明的奶牛可以产更多的牛奶.他为奶牛设计了一种智力游戏,名叫翻转棋. 翻转棋可以分成 M × N 个格子,每个格子有两种颜色,一面是黑的,一面是白的. 一旦 ...