【清澄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 整体二分,先把所有询问都存下来: 然后二分一个值,小于它的加到二维树状数组的前缀和里,判断一遍所有询问,就 ...
随机推荐
- -_-#【邮件】qq邮箱不显示图片
干货分享之邮件营销QQ邮箱IP白名单服务申请
- 【转】Xcode7真机调试iOS应用程序
原文网址:http://i.cnblogs.com/EditPosts.aspx?opt=1 近日苹果发布的新的Xcode7带来了许多特性,比如:swift语言比以前运行更快.功能更强.代码具有更高的 ...
- Linux下USB烧写uImage kernel
Linux下USB烧写uImage kernel 1.启动开发板,进入u-boot:(如果开发板中没有系统,可以通过用SD卡方式启动开发板进入) U-Boot 2011.06 (Mar 19 ...
- HDU 5914 Triangle 【构造】 (2016中国大学生程序设计竞赛(长春))
Triangle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- Codeforces 350B Resort
题目链接:http://codeforces.com/problemset/problem/350/B 一开始想复杂了,建了张图,结果效率太低T了.其实用数组存可以了,结果发现的时候快没时间了,修改好 ...
- linux平台MongoDB数据库安装
跟Ruiy哥一起玩转吧; <一,初始化玩转MongoDB> 1,关闭SElinux(Ruiy哥根据经验知红帽的SElinux架设就是个错误,还记得不管啥结构首先要关闭的就是它); 2,设置 ...
- Eclipse自动换行WordWrap插件
eclipse没有自动换行功能,需要安装插件wordwrap,方法请自行百度,可以参考下面的方法: http://jingyan.baidu.com/article/ce09321b7ba7042bf ...
- ListBoxControl 删除选择的项的方法
public void RemoveSelectItems<T>(BaseListBoxControl listControl) { var list ...
- EXCEL 如何将多个工作表或工作簿合并到一个工作表
在使用Excel 时,我们经常需要将多个工作表或工作簿合并到一个工作表中,这样我们就能快速地对数据进行分析和统计.对于一般用户而言,除了复制每个工作表后再粘贴,没有其他什么方法了.如果只是合并少数几个 ...
- PPT扁平化风格设计手册
钱文嘉:颜色选择,搭配 http://www.pptfans.cn/341917.html