[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 ...
随机推荐
- 图解如何用U盘重装系统
第一类方法: 原生U盘安装,本工具制作完的U盘启动菜单含Windows7操作系统安装功能,使用本功能可以将Win7系统完美移植到你的U盘中.本功能不用进PE不用虚拟光驱,不受FAT32和NTFS文件系 ...
- [转]使用Beaglebone Black的SPI
分类: Beaglebone Black2013-11-24 18:21 678人阅读 评论(6) 收藏 举报 beaglebone blackbeagleboneSPIdevice tree 目 ...
- Building and setting up QT environment for BeagleBone
There are too few information available on how to easily setup QT environment for building Beaglebon ...
- [转] 引用 Java自带的线程池ThreadPoolExecutor详细介绍说明和实例应用
PS: Spring ThreadPoolTaskExecutor vs Java Executorservice cachedthreadpool 引用 [轰隆隆] 的 Java自带的线程池Thre ...
- 自定义ContentProvider
ContentProvider作为安卓的四大组件之一,在看开发中用到的频率远不如其他三个,以至于我都把这个东西给忘了,最近由于工作原因,不得不重新拾起来总结一下,那么今天就来说说自定义ContentP ...
- TextView使用的方式
第一种改变TextView的方式 // TextView tv=new TextView(this); // tv.setText("Hello,Android&quo ...
- Java8特性---关于Null
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/5713941.html ...
- 那天有个小孩跟我说LINQ(二)转载
1 LINQ TO Objects续(代码下载) 新建项目 linq_Ch2控制台程序,新建一个Entity文件夹 1.1 学生成绩查询(练习Join) 有三张表如下 ...
- SQL Server调优系列基础篇 - 联合运算符总
前言 上两篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符的优化技巧,本篇我们总结联合运算符的使用方式和优化技巧. 废话少说,直接进入本篇的主题. 技术准备 基于SQL Server200 ...
- git github 使用教程
参考文章:文章地址: http://wuyuans.com/2012/05/github-simple-tutorial/ github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般 ...