BZOJ2738: 矩阵乘法(整体二分)
Description
Input
接下来N行N列一共N*N个数,表示这个矩阵;
再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。
Output
Sample Input
2 1
3 4
1 2 1 2 1
1 1 2 2 3
Sample Output
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: 矩阵乘法(整体二分)的更多相关文章
- BZOJ2738矩阵乘法——整体二分+二维树状数组
题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5 ...
- [BZOJ2738]矩阵乘法-[整体二分+树状数组]
Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. (N<=500,Q<=60000) Solution 考虑二分答案,问题转化为求矩阵内为1 ...
- [BZOJ2738]矩阵乘法 整体二分+二维树状数组
2738: 矩阵乘法 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1643 Solved: 715[Submit][Status][Discuss ...
- 【BZOJ2738】矩阵乘法 整体二分
[BZOJ2738]矩阵乘法 Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. Input 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列 ...
- 【BZOJ2738】矩阵乘法 [整体二分][树状数组]
矩阵乘法 Time Limit: 20 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 给你一个N*N的矩阵,不用算矩阵乘 ...
- 【bzoj2738】矩阵乘法 整体二分+二维树状数组
题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5个数 ...
- BZOJ 2738: 矩阵乘法 [整体二分]
给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 愚蠢的名字...... 整体二分,影响因子就是矩阵里的数 把$\le mid$的矩阵元素加到二维树状数组里然后询问分成两组就行 ...
- 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]
题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...
- BZOJ.2738.矩阵乘法(整体二分 二维树状数组)
题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...
随机推荐
- Android - TextureView, SurfaceView和GLSurfaceView 以及 SurfaceTexture
这几个概念比较绕, 又比较相近. 初看比较糊涂, 把握关键点就好. 关键字 View SurfaceViewGLSurfaceViewTextureView这三个后缀都是View, 所以这三个东西都是 ...
- 24. 在IDEA中使用JUnit进行方法测试
转自:https://blog.csdn.net/smxjant/article/details/78206279 1. 前文 刚学习到的新技能,对JUnit的了解也还是皮毛程度,在这里做个笔记.如果 ...
- Redis之创建
redis配置文件信息 public sealed class RedisConfigInfo { /// <summary> /// 可写的Redis链接地址 /// format:ip ...
- HAProxy高可用配置视频教程
HAProxy提供高可用性.负载均衡等,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理.HAProxy运行在当前的硬件上, ...
- javascript学习笔记总结
1 有些浏览器可能不支持JavaScript,我们可以使用如下的方法对它们隐藏JavaScript代码. <html> <body> <script type=" ...
- POSTGRESQL NO TABLE
POSTGRESQL EXTENDING SQL GRIGGER PROCEDURAL
- codeforces1114D. Flood Fill(区间Dp)
传送门: 解题思路: 区间Dp,发现某一个区间修改后区间颜色一定为左边或右边的颜色. 那么只需要设方程$f_(l,r,0/1)$表示区间$[l,r]$染成左/右颜色的最小代价 转移就是枚举左右颜色就好 ...
- hdu5024
思路要开阔些,或者说要转化一下思路,别太死 把每一个点当拐点,爆一边就能够.用记忆化搜索也行.都不会超时 #include<bits/stdc++.h> using namespace s ...
- Unity中uGUI的控件事件穿透逻辑
1.正常来说Image和Text是会拦截点击事件的,假设加入EventTrigger的话,就能够响应相应的交互事件. 2.假设Image和Text是一个Button的子控件.那么尽管其会显示在Butt ...
- Nginx安装以及配置
安装编译工具及库文件 1 yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel 安装 PCRE 下载 PC ...