矩阵乘法

【问题描述】

给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数。

【输入格式】

第一行两个数N,Q,表示矩阵大小和询问组数;
接下来N行N列一共N*N个数,表示这个矩阵;
再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。

【输出格式】

对于每组询问输出第K小的数。

【样例输入】

2 2
2 1
3 4
1 2 1 2 1
1 1 2 2 3
【样例输出】

1
3

【样例说明】

矩阵中数字是109以内的非负整数;
20%的数据:N<=100,Q<=1000;
40%的数据:N<=300,Q<=10000;
60%的数据:N<=400,Q<=30000;
100%的数据:N<=500,Q<=60000。


题解:

将每个点储存下来,排序一下,和询问进行二分

我们将小于等于当前枚举的答案(即为mid)的点加入树状数组

对于区间内的询问,查询子矩阵内的小于等于mid的个数,如果大于等于这个询问要求的k,将其放置在左区间,表示第k小在l到mid之间

否则放置在右区间,表示第k小在mid+1到r之间

 #include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline void Scan(int &x)
{
char c;
while((c = getchar()) < '' || c > '');
x = c - '';
while((c = getchar()) >= '' && c <= '')
x = x * + c - '';
}
const int maxn = ;
const int maxq = ;
struct dot
{
int x, y, v;
};
dot c[maxq];
struct ask
{
int x, y, a, b, c;
};
ask a[maxq];
int n, q;
int p;
int num;
int ans[maxq];
int id[maxq], tmp[maxq];
bool lr[maxq];
int tr[maxn][maxn];
inline void Ins(int x, int y, int z)
{
for(int i = x; i <= n; i += i & -i)
for(int j = y; j <= n; j += j & -j)
tr[i][j] += z;
}
inline int Ask(int x, int y)
{
int sum = ;
for(int i = x; i; i -= i & -i)
for(int j = y; j; j -= j & -j)
sum += tr[i][j];
return sum;
}
inline void Two(int x, int y, int l, int r)
{
if(x > y) return;
if(l == r)
{
for(int i = x; i <= y; ++i) ans[id[i]] = r;
return;
}
int mi = l + r >> ;
while(c[p + ].v <= mi) ++p, Ins(c[p].x, c[p].y, );
while(c[p].v > mi) Ins(c[p].x, c[p].y, -), --p;
int tot, cnt = ;
for(int i = x; i <= y; ++i)
{
int k = id[i];
tot = Ask(a[k].a, a[k].b) - Ask(a[k].a, a[k].y - ) - Ask(a[k].x - , a[k].b) + Ask(a[k].x - , a[k].y - );
if(tot >= a[k].c) lr[i] = true, ++cnt;
else lr[i] = false;
}
int le = x - , ri = x + cnt - ;
for(int i = x; i <= y; ++i)
if(lr[i]) tmp[++le] = id[i];
else tmp[++ri] = id[i];
for(int i = x; i <= y; ++i) id[i] = tmp[i];
Two(x, le, l, mi), Two(le + , ri, mi + , r);
}
inline bool rule(dot a, dot b)
{
return a.v < b.v;
}
int main()
{
Scan(n), Scan(q);
int val;
for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j)
{
Scan(val);
c[++num] = (dot) {i, j, val};
}
sort(c + , c + + num, rule);
for(int i = ; i <= q; ++i)
Scan(a[i].x), Scan(a[i].y), Scan(a[i].a), Scan(a[i].b), Scan(a[i].c), id[i] = i;
Two(, q, , c[num].v);
for(int i = ; i <= q; ++i) printf("%d\n", ans[i]);
}

矩阵乘法 BZOJ 2738的更多相关文章

  1. [BZOJ 2738] 矩阵乘法 【分块】

    题目链接:BZOJ - 2738 题目分析 题目名称 “矩阵乘法” 与题目内容没有任何关系..就像VFK的 A+B Problem 一样.. 题目大意是给定一个矩阵,有许多询问,每次询问一个子矩阵中的 ...

  2. 【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法

    整体二分+树状数组 过了[BZOJ][2527][POI2011]Meteors以后这题就没那么难啦~ 关键是[从小到大]依次插入数字,然后整体二分每个查询的第k大是在第几次插入中被插入的……嗯大概就 ...

  3. bzoj 2738 矩阵乘法

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

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

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

  5. [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】

    题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...

  6. [BZOJ 2326] [HNOI2011] 数学作业 【矩阵乘法】

    题目链接:BZOJ - 2326 题目分析 数据范围达到了 10^18 ,显然需要矩阵乘法了! 可以发现,向数字尾部添加一个数字 x 的过程就是 Num = Num * 10^k + x .其中 k ...

  7. [BZOJ 1875] [SDOI 2009] HH去散步【矩阵乘法】

    题目链接:BZOJ - 1875 题目分析: 这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了.然而现在加了这个限制,建图的方式就要做一些改变.如果我们把每一条边 ...

  8. bzoj 1009 [HNOI2008]GT考试(DP+KMP+矩阵乘法)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1009 [题意] 给定一个字符串T,问长度为n且不包含串T的字符串有多少种. [思路] ...

  9. bzoj 3240: [Noi2013]矩阵游戏 矩阵乘法+十进制快速幂+常数优化

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 613  Solved: 256[Submit][Status] ...

随机推荐

  1. leecode 旋转数组

    描述 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋 ...

  2. Java IO流之字符缓冲流

    字符流: 1.加入字符缓存流,增强读取功能(readLine) 2.更高效的读取数据 BufferedReader 从字符输入流读取文本,缓冲各个字符,从而实现字符.数组和行的高效读取. FileRe ...

  3. POJ2402 Palindrome Numbers第K个回文数——找规律

    问题 给一个数k,给出第k个回文数  链接 题解 打表找规律,详见https://www.cnblogs.com/lfri/p/10459982.html,差别仅在于这里从1数起. AC代码 #inc ...

  4. CPP-基础:C++的new int()与new int[]

    编写一个List类: class List { int length; //列表长度 int* lpInt; //列表指针 List(int size); ~List(); } List::List( ...

  5. QT +样式表

    学习样式表的目的:可以设计出好看的控件.(比如可以给一些按钮设计成好看的图片) QT 样式表的思想很大程度上是来自于HTML的层叠式样式表(CSS),通过调用QWidget->setStyleS ...

  6. 后台返回数据为treeList结构,如何添加属性(递归添加属性)

    给tree形json数据添加默写属性(递归)addAttr(data){ for (var j = 0; j < data.length; j++) { data[j].title = data ...

  7. Sql Server 自动备份

    1)启动代理服务 服务->Sql server 代理启动 2)设置维护计划 维护计划->设置维护计划向导->修改名称及说明 3)更改计划 4)选择维护任务 5)顺序调整不做解释 6) ...

  8. cdlinux

    xset q xset s 6000 xset -dpms ntpdate time.nist.gov date

  9. CF-1099 D. Sum in the tree

    CF-1099 D. Sum in the tree 题意:结点序号为 1~n 的一个有根树,根序号为1,每个点有一个权值a[i], 然后定义一s[i]表示从根节点到 结点序号为i的结点的路途上所经过 ...

  10. 一篇关于BEM命名规范

    一直以来自己对命名都是比较混乱的,并没有一个比较好的格式来命名,最近自己碰巧学习到了BEM命名规范,我想谈谈自己的理解以供自己来学习,同时也可以和各位大佬一起学习. BEM是一个很有用的方法可以创建复 ...