题目链接: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] 矩阵乘法 【分块】的更多相关文章

  1. bzoj 2738 矩阵乘法

    其实这题跟矩阵乘法没有任何卵关系,直接整体二分,用二维树状数组维护(刚刚学会>_<),复杂度好像有点爆炸(好像有十几亿不知道是不是算错了),但我们不能怂啊23333. #include&l ...

  2. BZOJ 2738: 矩阵乘法 [整体二分]

    给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 愚蠢的名字...... 整体二分,影响因子就是矩阵里的数 把$\le mid$的矩阵元素加到二维树状数组里然后询问分成两组就行 ...

  3. BZOJ 2738 矩阵乘法(整体二分+二维树状数组)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2738 [题目大意] 给出一个方格图,询问要求求出矩阵内第k小的元素 [题解] 我们对答 ...

  4. BZOJ.2738.矩阵乘法(整体二分 二维树状数组)

    题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...

  5. bzoj 2738: 矩阵乘法【整体二分+树状数组】

    脑子一抽开始写主席树,敲了一会发现不对-- 整体二分,用二维树状数组维护值为当前区间的格子个数,然后根据k的大小和当前询问的子矩阵里的值和k的大小关系来决定这个询问放在哪一部分向下递归 #includ ...

  6. bzoj 1297 矩阵乘法变形

    首先对于矩阵乘法的功能有很多,记得有篇论文叫矩阵乘法在信息学竞赛中的应用,里面详细介绍了矩阵的 作用 其中一个就是求图的固定时间方案数,也就是给定一张图,每两个点之间由一条边长为1的边相连, 求任意两 ...

  7. bzoj 2326 矩阵乘法

    [HNOI2011]数学作业 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2415  Solved: 1413[Submit][Status][Di ...

  8. 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)* ...

  9. BZOJ 2738 子矩阵第k大 | 二维树状数组 整体二分 分治

    BZOJ 2738 "矩阵乘法"(子矩阵第k大) 题意 给出一个矩阵,多次询问子矩阵中第k大的数是多少. 题解 我做这道题之前先照着这道题出了一道题,是这道题的一维版本,在这里:h ...

随机推荐

  1. Linux Bash终端快捷键小结

    Ctrl + A  定位至行首 Ctrl + E  定位至行尾 Ctrl + U  向前删除至行首 Ctrl + K  向后删除至行尾 Ctrl + L  清屏

  2. ModelAndView使用方法

    配置支持ModelAndView 在application.xml中配置支持ModelAndView,配置方式有两种. 配置一 <bean id="ViewResolver" ...

  3. Android开发5大布局方式详解

    Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...

  4. 第三篇:gradle 编译 Android app 概览

    引言:经过上两篇的论述,我们已经从代码到架构都简单的熟悉了一遍,理论上,只要知道android app的编译过程,我们大可以自己写一份用gradle编译app的插件,插件内将将整个流程用Task的依赖 ...

  5. MP4(一)-结构

    http://blog.csdn.net/zhuweigangzwg/article/details/17222951 一.基本概念 1.mp4概述 MP4文件中的所有数据都装在box(QuickTi ...

  6. CDN调度器HAProxy、Nginx、Varnish

    http://www.ttlsa.com/web/the-cdn-scheduler-nginx-haproxy-varnish/ CDN功能如下:1.将全网IP分为若干个IP段组,分组的依据通常是运 ...

  7. Block中的引用循环

    原文地址:http://www.cnblogs.com/lujianwenance/p/5910490.html Block在实际的开发中非常的常用,事件回调.传值.封装成代码块调用等等.很多人都对b ...

  8. XMPP适配IPV6 (GCDAsyncSocket适配IPV6)

    苹果公司要求在6月1号之后上架Appstore的应用必须通过ipv6兼容测试. 最近到了八月份,开始发现新上架的app没有通过,查看了下原因,说没有适配IPV6. 首先在本地搭建一个IPV6的测试环境 ...

  9. OC - 5.内存管理

    一.引用计数器 1> 栈和堆 栈 ① 主要存储局部变量 ② 内存自动回收 堆 ① 主要存储需要动态分配内存的变量 ② 需要手动回收内存,是OC内存管理的对象 2> 简介 作用 ① 表示对象 ...

  10. 反射 介绍System.Type类

    本节先介绍system.Type类,通过这个类可以访问关于任何数据类型的信息. 1. system.Type类以前把Type看作一个类,但它实际上是一个抽象的基类.只要实例化了一个Type对象,实际上 ...