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
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,不会超啊,可能是常数太大了。。。
猥琐的改了个读入加速,竟然过了。。。
世事无常。。。