[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 ...
随机推荐
- Java基础知识强化之集合框架笔记65:Map集合之集合多层嵌套的数据分析
1. 为了更符合要求: 这次的数据就看成是学生对象. 传智播客 bj 北京校区 jc 基础班 林青霞 27 风清扬 30 jy 就业班 赵雅芝 28 武鑫 29 sh 上海 ...
- 史上最全的JavaScript工作笔记
/* * JavaScript查看对象函数 */ function resultTest( obj ){ var resultTest = ''; $.each(obj,function(key,va ...
- ASP.NET MVC(二) 理解MVC
MVC模型同时提供对HTML.CSS以及JavaScript的完整控制. MVC模型通过三个逻辑层来定义WEB应用程序: (一)Business layer(业务层.模型逻辑) 模型(Model) 模 ...
- 谨以此错误警醒自己---java.lang.ClassNotFoundException:
今天在做一个小型的实例,用了面向接口编程,采用了工厂来获取数据源和实例,在从配置文件读取实例时,报了个错误如下图: 于是一个一个的类去找错误,最后也没找到,以为工厂代码出错了,看了好几次也没看出来错误 ...
- mysql相关重要问题解决
root密码修改 MySQL 的管理员密码: sudo mysqladmin -u root password newpassword: mysql无法安装:删除/etc/mysql, /var/ ...
- Objective-C 成员变量的访问修饰即成员变量可见性解析
总体来说Objective-C的访问成员变量可见性和C++基本一样,只是多了个@package. 以下是详细说明: 例子: @interface CTPerson : NSObject { @priv ...
- javascript函数 第14节
<html> <head> <title>function</title> </head> <body> 1.函数形式<b ...
- Map集合中的一些具体方法的体现
package com.java.b.map.www; import java.util.Collection;import java.util.HashMap;import java.util.It ...
- 03_天气查询_socket方式模拟_多线程方式
[简述] 要重视Socket开发,企业后台服务特长使用Socket. 1.服务端要有可持续运行能力,保证线程一致在运行 2.并发处理能力,使用多线程 [工程截图] [WeatherRunner.jav ...
- 九度OJ 1452 搬寝室 -- 动态规划
题目地址:http://ac.jobdu.com/problem.php?pid=1452 题目描述: 搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3 ...