BZOJ2738: 矩阵乘法
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: 矩阵乘法的更多相关文章
- [bzoj2738]矩阵乘法_整体二分_树状数组
矩阵乘法 bzoj-2738 题目大意:给定一个$n*n$的矩阵.每次给定一个矩阵求矩阵$k$小值. 注释:$1\le n\le 500$,$1\le q\le 6\cdot 10^4$. 想法: 新 ...
- 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: 矩阵乘法(整体二分)
Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. Input 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N*N个数,表示这个矩阵: ...
- BZOJ2738 矩阵乘法 【整体二分 + BIT】
题目链接 BZOJ2738 题解 将矩阵中的位置取出来按权值排序 直接整体二分 + 二维BIT即可 #include<algorithm> #include<iostream> ...
- 【分块】【链表】bzoj2738 矩阵乘法
http://www.cnblogs.com/jianglangcaijin/p/3460012.html 首先将矩阵的数字排序.设置size,每次将size个数字插入.插入时,我们用h[i][j]记 ...
- bzoj2738矩阵乘法
题意: 给你一个N*N的矩阵,没有修改,每次询问一个子矩形中的第K小数. 题目链接 思路: 当它只有一列时,其实就是区间第K大,也就是整体二分可以解决的. 现在到了二维,只需要将之前的树状数组改成二维 ...
- BZOJ2738 矩阵乘法(整体二分+树状数组)
单个询问二分答案即可,多组询问直接整体二分再二维BIT.注意保证复杂度. #include<iostream> #include<cstdio> #include<cma ...
随机推荐
- IOC原理解释
spring ioc它其实是一种降低对象耦合关系的设计思想,通常来说,我们在一个类调用另一个类的方法的时候,需要不断的new新的对象来调用该方法,类与类之间耦合度比较高,有了ioc容器以后,ico容器 ...
- Rehashing
The size of the hash table is not determinate at the very beginning. If the total size of keys is to ...
- 46. 对称子字符串的最大长度(ToDo)
[题目] 输入一个字符串,输出该字符串中对称的子字符串的最大长度.比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4. [分析] 可能很多人都写过判断一个字符串 ...
- iOS的 context 和Android 中的 canvas
ios 想要绘图,要用到CGContextRef类.最基本的用法是在- (void)drawRect:(CGRect)rect 函数中绘制. Android 中要用到Canvas类.最基本的用法是在 ...
- jQuery操作复选框的简单使用
开发中为了实现一个小功能,就是复选框的相互影响事件,如下图: 就是通过复选框设置权限,权限是分等级的,这是一个web管理系统的应用,一个管理员具有三个权限赋予,权限也是有等级的,其中删除和编辑权限相当 ...
- PHP--TP框架----操作数据库
//操作数据库 //$attr = $m->select(); //查询所有数据 //$attr = $m->s ...
- HDU 5734 Acperience (公式推导) 2016杭电多校联合第二场
题目:传送门. #include <iostream> #include <algorithm> #include <cstdio> #include <cs ...
- Replace Nested Conditional with Guard Clauses(用卫语句代替嵌套循环)
函数中的条件逻辑,使人难以看清正常的执行路径. 使用卫语句表现所有特殊情况. double getPayAmount() {double result;if (_isDead) result = de ...
- onItemClick 参数解释
X, Y两个listview,X里有1,2,3,4这4个item,Y里有a,b,c,d这4个item.如果你点了b这个item.如下:public void onItemClick (AdapterV ...
- pyinstaller--将py文件转化成exe
首先要注意一下:打包python文件成exe格式这个过程只能在windows环境下运行 1. 直接在命令行用pip安装 pyinstaller pip install pyinstaller</ ...