试题来源
  2012中国国家集训队命题答辩
问题描述
  给你一个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。
【分析】
其实用可持久化的线段树应该也可以做。
裸的整体二分题,把每个输入的点按权值排个序就可以了。
其实可以加一点修改什么的,这样加着修改一起二分难度稍微大一点。
本周在校最后一题,哈哈哈..
 /*
李商隐
《无题·重帏深下莫愁堂》
重帏深下莫愁堂,卧后清宵细细长。
神女生涯原是梦,小姑居处本无郎。
风波不信菱枝弱,月露谁教桂叶香。
直道相思了无益,未妨惆怅是清狂。
*/
#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】【整体二分+二维树状数组】矩阵乘法(梁盾)的更多相关文章

  1. [BZOJ2738]矩阵乘法(整体二分+二维树状数组)

    整体二分+二维树状数组. 好题啊!写了一个来小时. 一看这道题,主席树不会搞,只能用离线的做法了. 整体二分真是个好东西,啥都可以搞,尤其是区间第 \(k\) 大这种东西. 我们二分答案,然后用二维树 ...

  2. 【bzoj2738】矩阵乘法 整体二分+二维树状数组

    题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5个数 ...

  3. BZOJ2738矩阵乘法——整体二分+二维树状数组

    题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入   第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5 ...

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

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

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

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

  6. [BZOJ2738]矩阵乘法 整体二分+二维树状数组

    2738: 矩阵乘法 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1643  Solved: 715[Submit][Status][Discuss ...

  7. 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]

    题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...

  8. 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...

  9. 洛谷P1527 矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 整体二分,先把所有询问都存下来: 然后二分一个值,小于它的加到二维树状数组的前缀和里,判断一遍所有询问,就 ...

随机推荐

  1. -_-#【邮件】qq邮箱不显示图片

    干货分享之邮件营销QQ邮箱IP白名单服务申请

  2. 【转】Xcode7真机调试iOS应用程序

    原文网址:http://i.cnblogs.com/EditPosts.aspx?opt=1 近日苹果发布的新的Xcode7带来了许多特性,比如:swift语言比以前运行更快.功能更强.代码具有更高的 ...

  3. Linux下USB烧写uImage kernel

    Linux下USB烧写uImage kernel   1.启动开发板,进入u-boot:(如果开发板中没有系统,可以通过用SD卡方式启动开发板进入)   U-Boot 2011.06 (Mar 19 ...

  4. HDU 5914 Triangle 【构造】 (2016中国大学生程序设计竞赛(长春))

    Triangle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  5. Codeforces 350B Resort

    题目链接:http://codeforces.com/problemset/problem/350/B 一开始想复杂了,建了张图,结果效率太低T了.其实用数组存可以了,结果发现的时候快没时间了,修改好 ...

  6. linux平台MongoDB数据库安装

    跟Ruiy哥一起玩转吧; <一,初始化玩转MongoDB> 1,关闭SElinux(Ruiy哥根据经验知红帽的SElinux架设就是个错误,还记得不管啥结构首先要关闭的就是它); 2,设置 ...

  7. Eclipse自动换行WordWrap插件

    eclipse没有自动换行功能,需要安装插件wordwrap,方法请自行百度,可以参考下面的方法: http://jingyan.baidu.com/article/ce09321b7ba7042bf ...

  8. ListBoxControl 删除选择的项的方法

    public void RemoveSelectItems<T>(BaseListBoxControl listControl)        {            var list ...

  9. EXCEL 如何将多个工作表或工作簿合并到一个工作表

    在使用Excel 时,我们经常需要将多个工作表或工作簿合并到一个工作表中,这样我们就能快速地对数据进行分析和统计.对于一般用户而言,除了复制每个工作表后再粘贴,没有其他什么方法了.如果只是合并少数几个 ...

  10. PPT扁平化风格设计手册

    钱文嘉:颜色选择,搭配 http://www.pptfans.cn/341917.html