矩阵乘法

Time Limit: 20 Sec  Memory Limit: 256 MB
[Submit][Status][Discuss]

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。

Solution

  由于只有询问,我们可以方便地使用整体二分来求解。

  先将原矩阵以序列形式存下来,然后按照权值排序,接着我们二分序列上的位置来查询,在[l,mid]这一段序列上的点+1,然后像静态查Kth那么判断即可。(用二维树状数组加入权值)。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std; const int ONE = ;
const int QUE = ; int n,Q;
int tot;
int C[ONE][ONE];
int Ans[QUE]; struct point
{
int x,y,val;
}a[ONE*ONE];
bool cmp(const point &a,const point &b) {return a.val < b.val;} struct power
{
int x1,y1,x2,y2;
int k;
int id;
}oper[QUE],qL[QUE],qR[QUE]; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} namespace Bit
{
int lowbit(int x) {return x&-x;} void Add(int x,int y,int z)
{
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
C[i][j] += z;
} int Query(int x,int y)
{
int res = ;
for(int i=x;i>=;i-=lowbit(i))
for(int j=y;j>=;j-=lowbit(j))
res += C[i][j];
return res;
} int Getans(power a)
{
return Query(a.x2,a.y2) - Query(a.x1-,a.y2) - Query(a.x2,a.y1-) + Query(a.x1-,a.y1-);
}
} void Solve(int l,int r,int L,int R)//位置 询问
{
if(L>R) return;
if(l==r)
{
for(int i=L;i<=R;i++)
Ans[oper[i].id] = a[l].val;
return;
} int mid=(l+r)>>;
for(int i=l;i<=mid;i++)
Bit::Add(a[i].x,a[i].y,); int l_num=,r_num=;
for(int i=L;i<=R;i++)
{
int record = Bit::Getans(oper[i]);
if(record >= oper[i].k)
qL[++l_num] = oper[i];
else
oper[i].k-=record, qR[++r_num] = oper[i];
} for(int i=l;i<=mid;i++)
Bit::Add(a[i].x,a[i].y,-); int t=L;
for(int i=;i<=l_num;i++) oper[t++] = qL[i];
for(int i=;i<=r_num;i++) oper[t++] = qR[i]; Solve(l,mid,L,L+l_num-);
Solve(mid+,r,L+l_num,R);
} int main()
{
n=get(); Q=get();
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
a[++tot].val = get();
a[tot].x = i; a[tot].y = j;
}
sort(a+,a+tot+,cmp); for(int i=;i<=Q;i++)
{
oper[i].x1=get(); oper[i].y1=get(); oper[i].x2=get(); oper[i].y2=get();
oper[i].k=get(); oper[i].id=i;
} Solve(,tot,,Q); for(int i=;i<=Q;i++)
printf("%d\n",Ans[i]);
}

【BZOJ2738】矩阵乘法 [整体二分][树状数组]的更多相关文章

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

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

  2. 【BZOJ-2527】Meteors 整体二分 + 树状数组

    2527: [Poi2011]Meteors Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 831  Solved: 306[Submit][Stat ...

  3. 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  4. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  5. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  6. 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组

    题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...

  7. 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组

    题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...

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

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

  9. 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...

随机推荐

  1. webapi到处excel

    最近项目用的webapi前几天做了个导出excel功能,给大家分享下,自己也记录下... 在用的过程中,可以直接请求就可以得到下载的excel文件,在实际的项目中可以通过js打开新页面,encodeU ...

  2. MyEclipse - 问题集 - 创建Maven项目,JDK版本默认是1.5

    修改Maven的配置文件settings.xml,增加profile节点,如下所示: <profile> <id>jdk-1.8</id> <activati ...

  3. Delphi实例之绘制正弦函数图像

    Delphi实例之绘制正弦函数图像 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphic ...

  4. Android 序列化比对

    本文转自:https://www.zybuluo.com/linux1s1s/note/91046 注:部分内容有更改 在Android中使用序列化,无非两种途经: Parcelable 和 Seri ...

  5. C#文件重命名的代码

    C#中没有重命名的方法,自己写了一个方法,来处理文件的重命名. /// <summary> /// 重命名文件夹内的所有子文件夹 /// </summary> /// < ...

  6. (Python爬虫01)-本想给随笔加个序号才发现这么不方便

    本想给随机加个序号,才发现还得去返回看看文章的序号.好在cnblog能断点自动保存. 作为一个小程序员,点赞的同时还在想,谁知道咋实现这种实时保存呢?有知道的给个参考文档呗.太感激了! 重点在这里 有 ...

  7. 牛客 小a与星际探索

    链接:https://ac.nowcoder.com/acm/contest/317/C来源:牛客网 小a正在玩一款星际探索游戏,小a需要驾驶着飞船从1号星球出发前往n号星球.其中每个星球有一个能量指 ...

  8. python基础训练营04-函数

    任务四  函数的关键字 函数的定义 函数参数与作用域 函数返回值 一.函数的关键字: def 二.函数的定义: 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号 ...

  9. 【虚拟货币钱包】从 BIP32、BIP39、BIP44 到 Ethereum HD Wallet

    干货 | [虚拟货币钱包]从 BIP32.BIP39.BIP44 到 Ethereum HD Wallet {{uploading-image-882090.png(uploading...)}}

  10. AM5728通过GPMC接口与FPGA高速数据通信实现

    硬件:AM5728开发板:Artix-7开发板软件:Linux am57xx-evm 4.4.19:Vivado 2015.2作者:杭州矢志信息科技有限公司邮箱:admin@sysjoint.com ...