1. 程式人生 > >Codeforces Gym 100741G Yet Another Median Task 二分亂搞

Codeforces Gym 100741G Yet Another Median Task 二分亂搞

G. Yet Another Median Task time limit per test 2.0 s memory limit per test 64 MB input standard input output standard output

You're given a matrix a with n lines and n columns. We define the median of an array the element from the middle position of sorted array. If there are two such positions (n is even), get the element whose position is minimal.

Answer q queries of form: what's the median element of a submatrix (x1, y1, x2, y2). Formally, we consider all elements a[i][j] such as x1 <= i <= x2 and y1 <= j <= y2 and add them into a temporary array. Then, get the median of the array.

Input

First line of the input contains numbers n (1 ≤ n ≤ 800) and q (1 ≤ q ≤ 1000). Next n lines contain nnumbers, describing the 1-based matrix a. All elements from a can fit into an int type. Next q lines contain numbers x1, y1, x2, y2, describing a query (1 ≤ x1 ≤ x2 ≤ n , 1 ≤ y1 ≤ y2 ≤ n)

Output

Output q lines, each line to answer a query.

Examples input
2 4
1 2
2 2
1 1 2 1
1 1 1 2
1 1 2 2
2 2 2 2
output
1
1
2
2

給你一個矩陣,q次詢問,每次問你子矩陣拉成一維陣列排序後的中位數是多少。

二分答案,每次二分把子矩陣掃一遍,看比當前二分數字小的數有多少個。

這樣亂搞也能過,真心佩服自己啊~ (小小自戀一把

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=805,inf=0x3f3f3f3f;  
const ll llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);  
int a[maxn][maxn];
int p[maxn*maxn];

int main() {
	int n,i,j,k,l,r,u,d,q;
	ll m=-llinf,w=llinf;
	scanf("%d%d",&n,&q);
	for (i=1;i<=n;i++) {
		for (j=1;j<=n;j++) {
			scanf("%d",&a[i][j]);
			m=max(m,(ll)a[i][j]);
			w=min(w,(ll)a[i][j]);
		}
	}
	for (i=1;i<=q;i++) {
		scanf("%d%d%d%d",&u,&l,&d,&r);
		int lc=w,rc=m,mid,tot=(r-l+1)*(d-u+1),ans;
		if (tot%2) tot/=2; else tot=tot/2-1;
		while (lc<=rc) {
		int cnt=0;
		mid=(lc+rc)/2;
		for (j=u;j<=d;j++) {
			for (k=l;k<=r;k++) {
				if (a[j][k]<mid) cnt++;
			}
		}
		if (cnt<=tot) lc=mid+1,ans=mid; else {
			rc=mid-1;
		}
	    }
	    printf("%d\n",ans);
	}
	return 0;
}