【清澄A1333】【整体二分+二维树状数组】矩阵乘法(梁盾)
接下来N行N列一共N*N个数,表示这个矩阵;
再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。
2 1
3 4
1 2 1 2 1
1 1 2 2 3
3
20%的数据:N<=100,Q<=1000;
40%的数据:N<=300,Q<=10000;
60%的数据:N<=400,Q<=30000;
100%的数据:N<=500,Q<=60000。
/*
李商隐
《无题·重帏深下莫愁堂》
重帏深下莫愁堂,卧后清宵细细长。
神女生涯原是梦,小姑居处本无郎。
风波不信菱枝弱,月露谁教桂叶香。
直道相思了无益,未妨惆怅是清狂。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int MAXN = + ;
const int MAXM = + ;
const int INF = ;
const int SIZE = ;
const int maxnode = + ;
using namespace std;
typedef long long ll;
using namespace std;
int n, m, cnt;
int pos, Maxv;
int c[MAXN][MAXN], Ans[MAXM];
int id[MAXM];
int tmp[MAXM];
bool mark[MAXM]; struct DATA{
//横纵坐标和值
int x, y, val;
bool operator < (const DATA &b)const {
return val < b.val;
}
}data[maxnode];
//问题
struct QUESTION{
int x1, x2;
int y1, y2, K;
}q[MAXM];
//输入 inline int lowbit(int x){return x & -x;}
//插入
void add(int x, int y, int val){
int f = y;
while (x <= n){
while (y <= n){
c[x][y] += val;
y += lowbit(y);
}
y = f;
x += lowbit(x);
}
return;
}
int sum(int x, int y){//和
int tmp = , f = y;
while (x > ){
while (y > ){
tmp += c[x][y];
y -= lowbit(y);
}
y = f;
x -= lowbit(x);
}
return tmp;
}
//查询
int query(int k){
int x1, x2, y1, y2;
x1 = q[k].x1;x2 = q[k].x2;
y1 = q[k].y1;y2 = q[k].y2;
return sum(x2, y2) + sum(x1 - , y1 - ) - sum(x1 - , y2) - sum(x2, y1 - );
}
//整体二分
void solve(int l, int r, int L, int R){
if (l > r || L == R) return;//l和r是问题的编号
int mid = (L + R) >> ; while (data[pos + ].val <= mid && pos < cnt){//直接模拟
add(data[pos + ].x, data[pos + ].y, );
pos++;
}
while (data[pos].val > mid){
add(data[pos].x, data[pos].y , -);
pos--;
}
int cnt = ;
for (int i = l; i <= r; i++){
if (query(id[i]) > q[id[i]].K - ){
mark[i] = ;
Ans[id[i]] = mid;
cnt++;
}else mark[i] = ;
}
int l1 = l, l2 = l + cnt;
for (int i = l; i <= r; i++)
if (mark[i]) tmp[l1++] = id[i];
else tmp[l2++] = id[i];
//分成两部分继续整体二分
for (int i = l; i <= r; i++) id[i] = tmp[i];
solve(l, l1 - , L, mid);
solve(l1, l2 - , mid + , R);
} void init(){
memset(mark, , sizeof(mark));
memset(c, , sizeof(c));
scanf("%d%d", &n, &m);
Maxv = ;
cnt = ;
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++){
scanf("%d", &data[++cnt].val);
data[cnt].x = i;//横纵坐标
data[cnt].y = j;
Maxv = max(data[cnt].val, Maxv);
}
sort(data + , data + + cnt);
}
void work(){
for (int i = ; i <= m; i++){
scanf("%d%d%d%d%d", &q[i].x1, &q[i].y1, &q[i].x2, &q[i].y2, &q[i].K);
}
for (int i = ; i <= m; i++) id[i] = i;//问题序列
solve(, m, , Maxv + );
for (int i = ; i <= m; i++) printf("%d\n", Ans[i]);
} int main(){ init();
work();
return ;
}
【清澄A1333】【整体二分+二维树状数组】矩阵乘法(梁盾)的更多相关文章
- [BZOJ2738]矩阵乘法(整体二分+二维树状数组)
整体二分+二维树状数组. 好题啊!写了一个来小时. 一看这道题,主席树不会搞,只能用离线的做法了. 整体二分真是个好东西,啥都可以搞,尤其是区间第 \(k\) 大这种东西. 我们二分答案,然后用二维树 ...
- 【bzoj2738】矩阵乘法 整体二分+二维树状数组
题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5个数 ...
- BZOJ2738矩阵乘法——整体二分+二维树状数组
题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5 ...
- BZOJ.2738.矩阵乘法(整体二分 二维树状数组)
题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...
- BZOJ 2738 矩阵乘法(整体二分+二维树状数组)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2738 [题目大意] 给出一个方格图,询问要求求出矩阵内第k小的元素 [题解] 我们对答 ...
- [BZOJ2738]矩阵乘法 整体二分+二维树状数组
2738: 矩阵乘法 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1643 Solved: 715[Submit][Status][Discuss ...
- 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]
题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...
- 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分
题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...
- 洛谷P1527 矩阵乘法——二维树状数组+整体二分
题目:https://www.luogu.org/problemnew/show/P1527 整体二分,先把所有询问都存下来: 然后二分一个值,小于它的加到二维树状数组的前缀和里,判断一遍所有询问,就 ...
随机推荐
- 可压Navier-Stokes方程组的爆破现象
在 Z.P. Xin, Blowup of smooth solutions to the compressible Navier-Stokes equations with compact den ...
- word中MathType公式不能 二次编辑解决方案
问题:当新建文档然后插入公式,此时可以利用mathtype进行编辑,保存后推出第二次打开,双击公式却发现不能编辑公式. 解决方案: ////////////////////////////////// ...
- poj 2068 Nim(博弈树)
Nim Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 1501 Accepted: 845 Description Le ...
- 排序Tip
排序算法 所有排序算法汇总:http://en.wikipedia.org/wiki/Sort_algorithm counting sort 资料 :http://www.cs.miami.ed ...
- [CSS]利用伪元素实现一些特殊图形
给定的html代码是: <div class='square'></div> 平常实现我们常是通过添加小的icon来实现,不仅需要添加图片资源,还需要改动html结构. CSS ...
- VirtualBox的usb支持
解决usb支持: 0. 下载Oracle_VM_VirtualBox_Extension_Pack-4.0.4-70112.vbox-extpack后双击即可采用VB安装,若还是用ark打开可人为设置 ...
- MySQL基础 (DML)
DML语句 DML操作是指对数据库中表记录的操作,主要包括表记录的插入(insert).更新(update).删除(delete)和查询(select) 1.插入记录 插入一条 ...
- Spark1.0.0 监测方法
Spark1.0.0能够通过下面几种方式来对Spark应用程序进行监控: Spark应用程序的WebUI或者Spark Standalone的集群监控 指标,然后通过支持指标收集的集群监控 ...
- UML进行Linux内核调试
http://www.lenky.info/ http://blog.csdn.net/ztz0223/article/details/7874759 http://user-mode-linux.s ...
- linux下daemon守护进程的实现(以nginx代码为例)
ngx_int_t ngx_daemon(ngx_log_t *log) { int fd; // 让init进程成为新产生进程的父进程: // 调用fork函数创建子进程后,使父进程立即退出.这样, ...