EOJ 1086 Max discrepancy

Max discrepancy

Time Limit:1000MSMemory Limit:30000KB
Total Submit:138Accepted:57

Description

Solofanfy is busy with his farm,at this time,his little dog ask him to do some algorithm with his farmland,
Solofanfy has, at great expense, surveyed his square farm of N x N hectares (1 <= N <= 250). Each hectare has an integer elevation (0 <= elevation <= 250) associated with it.

Solofanfy will present your program with the elevations and a set of K (1 <= K <= 100,000) queries of the form "in this B x B submatrix, what is the maximum and minimum elevation?". The integer B (1 <= B <= N) is the size of one edge of the square cornfield and is a constant for every inquiry. Help FJ find the best place to put his cornfield.

Input

There are many test cases.
* Line 1: Three space-separated integers: N, B, and K.

* Lines 2..N+1: Each line contains N space-separated integers. Line 2 represents row 1; line 3 represents row 2, etc. The first integer on each line represents column 1; the second integer represents column 2; etc.

* Lines N+2..N+K+1: Each line contains two space-separated integers representing a query. The first integer is the top row of the query; the second integer is the left column of the query. The integers are in the range 1..N-B+1.

Output

* Lines 1..K: A single integer per line representing the difference between the max and the min in each query.

Sample Input

5 3 2
65 49 26 70 9
67 85 18 59 1
36 96 89 48 68
66 93 46 99 55
66 11 59 75 80
1 1
2 2

Sample Output

78

81



题目意思,就是给一个250*250的矩阵,10w次询问字矩阵中的最大最小值的差值。

题目有N^3的解法,因为字矩阵的大小是固定的,只是起点在变,开个数组记录一下,N^3更新就好了。

最近老长时间没搞数据结构了,就敲了个二维线段树,可能写的有些罗嗦,从感觉更新什么的有些重复,还好只是更新一下最大最小值,要再来个区间合并,估计我就跪了。

注意子树的更新,母树的更新也要从底下更新上来。



#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
 
using namespace std;
 
const int maxn = 1000;
struct sub_t{
	int l,r;
	int maxx;
	int minn;
};
struct tree{
	int l,r;
	//int maxx;
	sub_t s_t[maxn];
};
tree t[maxn];
int a[maxn][maxn];
int n;
int ans[255][255];
inline int INP(){
	int x = 0;
	char c;
	while((c = getchar()) != ' ' && c != '\n'){
		x = x * 10 + c - '0';
	}
	return x;
}
void build_subtree(int rt,int sb_rt,int l,int r,int id){
	//printf("rt = %d sb_rt = %d l = %d r = %d\n",rt,sb_rt,l,r);
	t[rt].s_t[sb_rt].l = l;
	t[rt].s_t[sb_rt].r = r;
	if(l == r){
		if(id != -1){
			//printf("rt = %d sb_rt = %d id = %d l = %d\n",rt,sb_rt,id,l);
			t[rt].s_t[sb_rt].maxx = a[id][l];
			t[rt].s_t[sb_rt].minn = a[id][l];
			//printf("rt = %d sb_rt = %d mx = %d mi = %d\n",rt,sb_rt,t[rt].s_t[sb_rt].maxx,t[rt].s_t[sb_rt].minn);
		}
		//else {
		//	t[rt].s_t[sb_rt].maxx = max(t[rt<<1].s_t[sb_rt].maxx,t[rt<<1|1].s_t[sb_rt].maxx);
		//	t[rt].s_t[sb_rt].minn = min(t[rt<<1].s_t[sb_rt].minn,t[rt<<1|1].s_t[sb_rt].minn);
		//}
		return ;
	}
	int mid = (l + r)>>1;
	build_subtree(rt,sb_rt<<1,l,mid,id);
	build_subtree(rt,sb_rt<<1|1,mid + 1,r,id);
	//printf("id = %d\n",id);
	if(id != -1){
		//printf("rt = %d sb_rt = %d sb_rt<<1 = %d sb_rt<<1|1 = %d\n",rt,sb_rt,sb_rt<<1,sb_rt<<1|1);
		//printf("lx = %d rx = %d\n",t[rt].s_t[sb_rt<<1].maxx,t[rt].s_t[sb_rt<<1|1].maxx);
		t[rt].s_t[sb_rt].maxx = max(t[rt].s_t[sb_rt<<1].maxx,t[rt].s_t[sb_rt<<1|1].maxx);
		t[rt].s_t[sb_rt].minn = min(t[rt].s_t[sb_rt<<1].minn,t[rt].s_t[sb_rt<<1|1].minn);
		//printf("rt = %d sb_rt = %d id = %d l = %d r = %d maxx = %d minn = %d\n",rt,sb_rt,id,t[rt].s_t[sb_rt].l,t[rt].s_t[sb_rt].r,t[rt].s_t[sb_rt].maxx,t[rt].s_t[sb_rt].minn);
	}
	//else {
	//	printf("rt = %d sb_rt = %d\n",rt,sb_rt);
	//	printf("lx = %d rx = %d\n",t[rt<<1].s_t[sb_rt].maxx,t[rt<<1|1].s_t[sb_rt].maxx);
	//	t[rt].s_t[sb_rt].maxx = max(t[rt<<1].s_t[sb_rt].maxx,t[rt<<1|1].s_t[sb_rt].maxx);
	//	t[rt].s_t[sb_rt].minn = min(t[rt<<1].s_t[sb_rt].minn,t[rt<<1|1].s_t[sb_rt].minn);
	//}
}
void push_up(int rt,int sb_rt,int l,int r){
	if(l == r){
		t[rt].s_t[sb_rt].maxx = max(t[rt<<1].s_t[sb_rt].maxx,t[rt<<1|1].s_t[sb_rt].maxx);
		t[rt].s_t[sb_rt].minn = min(t[rt<<1].s_t[sb_rt].minn,t[rt<<1|1].s_t[sb_rt].minn);
		return ;
	}
	int mid = (l + r)>>1;
	push_up(rt,sb_rt<<1,l,mid);
	push_up(rt,sb_rt<<1|1,mid + 1,r);
	//printf("push rt = %d sb_rt = %d\n",rt,sb_rt);
	t[rt].s_t[sb_rt].maxx = max(t[rt<<1].s_t[sb_rt].maxx,t[rt<<1|1].s_t[sb_rt].maxx);
	t[rt].s_t[sb_rt].minn = min(t[rt<<1].s_t[sb_rt].minn,t[rt<<1|1].s_t[sb_rt].minn);
	//printf("rt = %d sb_rt = %d l = %d r = %d d = %d u = %d maxx = %d minn = %d\n",rt,sb_rt,t[rt].l,t[rt].r,t[rt].s_t[sb_rt].l,t[rt].s_t[sb_rt].r,t[rt].s_t[sb_rt].maxx,t[rt].s_t[sb_rt].minn);
}
void build(int rt,int l,int r){
	t[rt].l = l;
	t[rt].r = r;
	if(l == r){
		build_subtree(rt,1,1,n,l);
		return ;
	}
	else build_subtree(rt,1,1,n,-1);
	int mid = (l + r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid + 1,r);
	push_up(rt,1,1,n);
	//t[rt].l = 
	//t[rt].maxx = max(t[rt<<1].maxx,t[rt<<1|1].maxx);
}
int query_subtree(int rt,int sb_rt,int l,int r,bool can){
	//printf("sub rt = %d sb_rt = %d sl = %d l = %d sr = %d r = %d\n",rt,sb_rt,t[rt].s_t[sb_rt].l,l,t[rt].s_t[sb_rt].r,r);
	if(t[rt].s_t[sb_rt].l >= l && t[rt].s_t[sb_rt].r <= r){
		//printf("ma = %d mi = %d\n",t[rt].s_t[sb_rt].maxx,t[rt].s_t[sb_rt].minn);
		if(can)return t[rt].s_t[sb_rt].maxx;
		return t[rt].s_t[sb_rt].minn;
	}
	int mid = (t[rt].s_t[sb_rt].l + t[rt].s_t[sb_rt].r)>>1;
	if(l > mid)return query_subtree(rt,sb_rt<<1|1,l,r,can);
	else if(r <= mid)return query_subtree(rt,sb_rt<<1,l,r,can);
	else {
		if(can)return max(query_subtree(rt,sb_rt<<1,l,mid,can),query_subtree(rt,sb_rt<<1|1,mid + 1,r,can));
		return min(query_subtree(rt,sb_rt<<1,l,mid,can),query_subtree(rt,sb_rt<<1|1,mid + 1,r,can));
	}
}
int query(int rt,int l,int r,int d,int u,bool can){
	//printf("rt = %d tl = %d l = %d tr = %d r = %d d = %d u = %d\n",rt,t[rt].l,l,t[rt].r,r,d,u);
	if(t[rt].l >= l && t[rt].r <= r){
		return query_subtree(rt,1,d,u,can);
	}
	int mid = (t[rt].l + t[rt].r)>>1;
	if(l > mid)return query(rt<<1|1,l,r,d,u,can);
	else if(r <= mid)return query(rt<<1,l,r,d,u,can);
	else {
		if(can)return max(query(rt<<1,l,mid,d,u,can),query(rt<<1|1,mid + 1,r,d,u,can));
		return min(query(rt<<1,l,mid,d,u,can),query(rt<<1|1,mid + 1,r,d,u,can));
	}
}
int main(){
	int b,m;
	while(scanf("%d%d%d",&n,&b,&m) != EOF){
 
		memset(ans,-1,sizeof(ans));
		for(int i = 1;i <= n;i ++){
			for(int j = 1;j <= n;j ++){
				scanf("%d",&a[i][j]);
			}
		}
		getchar();
		build(1,1,n);
		for(int i = 0;i < m;i ++){
			int x = INP(),y = INP();
			//scanf("%d%d",&x,&y);
			if(ans[x][y] != -1){
				printf("%d\n",ans[x][y]);
				continue;
			}
			int maxx = query(1,x,x + b - 1,y,y + b - 1,1);
			int minn = query(1,x,x + b - 1,y,y + b - 1,0);
			//printf("maxx = %d minn = %d\n",maxx,minn);
			printf("%d\n",maxx - minn);
			ans[x][y] = maxx - minn;
		}
		//break;
	}
	return 0;
}

上机课闲着没事,手贱点开了这个题,写了两节课还没写完,思路不清啊。

第二天两节数值计算的上机也搭上了。。。

晚上一直在debug,好不容易把更新想明白,过了几组数据,交了一发,wa

继续调,还是更新的问题。。

继续交,T。。。

瞬间没希望了,M*logn*logn,不会超啊,可能是常数太大了。。。

猥琐的改了个读入加速,竟然过了。。。

世事无常。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值