[BZOJ 2738] 矩阵乘法 【分块】
题目链接:BZOJ - 2738
题目分析
题目名称 “矩阵乘法” 与题目内容没有任何关系..就像VFK的 A+B Problem 一样..
题目大意是给定一个矩阵,有许多询问,每次询问一个子矩阵中的第 k 小值。
我看了神犇的题解,使用一种非常神奇的做法:
将矩阵中的数排个序,从小到大填到矩阵中。每次填 Size 个(这里就是分块)。
然后每填完一次,就暴力重新求一下 Sum[][] (二维前缀和), 然后枚举每个询问,看看这个询问的子矩形内已经填入的数是否不少于询问的 k 。
如果子矩形内已填入的数不少于询问的 k ,那么这个询问的答案一定就是在这一次填入的 Size 个数中,于是就枚举这 Size 个数,然后判断每个数是不是在子矩形内,就可以求出刚好填到第 k 个是哪个数了。
然后就可以将这次询问删掉了,用双向链表实现删除一个询问。
复杂度是 O(n^4 / Size + n^2 * q / Size + q * Size) ,然后用均值不等式求出一个最优的 Size 就可以了。
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; typedef double LF; inline int gmin(int a, int b) {return a < b ? a : b;} const int MaxN = 500 + 5, MaxM = 60000 + 5; int n, m, Top, Blk, S, T;
int Sum[MaxN][MaxN], Has[MaxN][MaxN]; struct ENum
{
int Num, x, y;
} E[MaxN * MaxN]; inline bool Cmp(ENum e1, ENum e2)
{
return e1.Num < e2.Num;
} struct EQ
{
int x, y, xx, yy, k, Ans, Prev, Next; bool Inside(ENum e)
{
return (e.x >= x && e.x <= xx) && (e.y >= y && e.y <= yy);
}
} Q[MaxM]; inline int GetSum(int x, int y, int xx, int yy)
{
return Sum[xx][yy] - Sum[x - 1][yy] - Sum[xx][y - 1] + Sum[x - 1][y - 1];
} int main()
{
scanf("%d%d", &n, &m);
Blk = (int)((LF)n * (1.0 + ((LF)n / sqrt((LF)m)))) + 1;
Top = 0;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
{
scanf("%d", &E[++Top].Num);
E[Top].x = i; E[Top].y = j;
}
sort(E + 1, E + Top + 1, Cmp);
for (int i = 1; i <= m; ++i)
scanf("%d%d%d%d%d", &Q[i].x, &Q[i].y, &Q[i].xx, &Q[i].yy, &Q[i].k);
for (int i = 1; i < m; ++i) Q[i].Next = i + 1;
for (int i = 2; i <= m; ++i) Q[i].Prev = i - 1;
S = m + 1; T = m + 2;
Q[S].Next = 1; Q[1].Prev = S;
Q[m].Next = T; Q[T].Prev = m;
int p;
for (int i = 1; i <= Top; i += Blk)
{
p = gmin(i + Blk - 1, Top);
for (int j = i; j <= p; ++j)
Has[E[j].x][E[j].y] = 1;
for (int j = 1; j <= n; ++j)
for (int k = 1; k <= n; ++k)
Sum[j][k] = Sum[j - 1][k] + Sum[j][k - 1] - Sum[j - 1][k - 1] + Has[j][k];
int j = Q[S].Next;
while (j != T)
{
int CntNow = GetSum(Q[j].x, Q[j].y, Q[j].xx, Q[j].yy);
if (CntNow >= Q[j].k)
{
int Pos = p;
while (CntNow >= Q[j].k)
{
if (Q[j].Inside(E[Pos])) --CntNow;
--Pos;
}
Q[j].Ans = E[Pos + 1].Num;
Q[Q[j].Next].Prev = Q[j].Prev;
Q[Q[j].Prev].Next = Q[j].Next;
}
j = Q[j].Next;
}
}
for (int i = 1; i <= m; ++i) printf("%d\n", Q[i].Ans);
return 0;
}
[BZOJ 2738] 矩阵乘法 【分块】的更多相关文章
- bzoj 2738 矩阵乘法
		
其实这题跟矩阵乘法没有任何卵关系,直接整体二分,用二维树状数组维护(刚刚学会>_<),复杂度好像有点爆炸(好像有十几亿不知道是不是算错了),但我们不能怂啊23333. #include&l ...
 - BZOJ 2738: 矩阵乘法 [整体二分]
		
给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 愚蠢的名字...... 整体二分,影响因子就是矩阵里的数 把$\le mid$的矩阵元素加到二维树状数组里然后询问分成两组就行 ...
 - BZOJ 2738 矩阵乘法(整体二分+二维树状数组)
		
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2738 [题目大意] 给出一个方格图,询问要求求出矩阵内第k小的元素 [题解] 我们对答 ...
 - BZOJ.2738.矩阵乘法(整体二分 二维树状数组)
		
题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...
 - bzoj 2738: 矩阵乘法【整体二分+树状数组】
		
脑子一抽开始写主席树,敲了一会发现不对-- 整体二分,用二维树状数组维护值为当前区间的格子个数,然后根据k的大小和当前询问的子矩阵里的值和k的大小关系来决定这个询问放在哪一部分向下递归 #includ ...
 - bzoj 1297 矩阵乘法变形
		
首先对于矩阵乘法的功能有很多,记得有篇论文叫矩阵乘法在信息学竞赛中的应用,里面详细介绍了矩阵的 作用 其中一个就是求图的固定时间方案数,也就是给定一张图,每两个点之间由一条边长为1的边相连, 求任意两 ...
 - bzoj 2326 矩阵乘法
		
[HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2415 Solved: 1413[Submit][Status][Di ...
 - bzoj 3240 矩阵乘法+十进制快速幂
		
首先,构造出从f[][i]->f[][i+1]的转移矩阵a,和从f[i][m]->f[i+1][1]的转移矩阵b, 那么从f[1][1]转移到f[n][m]就是init*(a^(m-1)* ...
 - BZOJ 2738 子矩阵第k大 | 二维树状数组 整体二分 分治
		
BZOJ 2738 "矩阵乘法"(子矩阵第k大) 题意 给出一个矩阵,多次询问子矩阵中第k大的数是多少. 题解 我做这道题之前先照着这道题出了一道题,是这道题的一维版本,在这里:h ...
 
随机推荐
- 移动终端学习一:css3 Media Queries简介
			
移动终端学习之一 css3 Media Queries简介 1.简介 别人写过的我就不重复了,来个链接:http://www.w3cplus.com/content/css3-media-querie ...
 - 练习PopupWindow弹出框之实现界面加载的时候显示弹出框到指定的view下面--两种延迟方法
			
今天在练习PopupWindow弹出框的时候,打算在界面加载的时候将弹出框展现出来并显示在指定的view下面. 初步方法是直接在OnResume方法里面直接执行showPopupWindows方法. ...
 - oracle从各个表取得数据保存到另一个表
			
从各个表中取得数据保存另一个表中: CREATE VIEW PARAMETER_view ASWITH tall AS ( SELECT p.PI_NO,--产品序列号 p.SERIALNO,--产品 ...
 - Windwos平台上ffmpeg解码音频并且保存到wav文件中
			
先附上代码,测试通过 #include <stdio.h> #include <math.h> #include "libavutil/avstring.h" ...
 - MongoDB源码分析——mongo与JavaScript交互
			
mongo与JavaScript交互 源码版本为MongoDB 2.6分支 之前已经说过mongo是MongoDB提供的一个执行JavaScript脚本的客户端工具,执行js其实就是一个js和 ...
 - HTTP中Get与Post、ViewState 原理
			
Http是请求,响应的模型,服务器不会来读取浏览器的网页,只能够得到客户端提交过来的数据当用户点击提交,服务器就知道"提交回来了"(PostBack) Get与Post 设置for ...
 - java中的JSON对象的使用
			
申明:没工作之前都没听过JSON,可能是自己太菜了.可能在前台AJAX接触到JSON,这几天要求在纯java的编程中,返回JSON字符串形式. 网上有两种解析JSON对象的jar包:JSON-lib. ...
 - FBX SDK 从2012.1 到 2013.3 变化
			
==================================================== ============================== 译文 ...
 - php 遍历一个文件夹下的所有文件和子文件夹
			
<?php function my_scandir($dir) { $files=array(); if(is_dir($dir)) { if($handle=opendir($dir)) { ...
 - corosync+pacemaker and drbd实现mysql高可用集群
			
DRBD:Distributed Replicated Block Device 分布式复制块设备,原理图如下 DRBD 有主双架构和双主架构的,当处于主从架构时,这个设备一定只有一个节点是可以读写的 ...