zoj 1716 || poj 2029 Get Many Persimmon Trees

二维树状数组分类下的题,开始不会,只想到了枚举行列,居然A掉了= =。。。

 

后来学习了一下二维树状数组,觉得好神奇啊。。。

 

二维的话 ,Updata函数里的参数是两个,进行二重循环,Getsum里也是,开始一直错,因为我把俩循环写错了 = =。。。用的while循环,后来见别人都用for循环,觉得还是for循环短啊。。

 

这个用树状数组做法就是,树状数组里的Getsum(x,y)得到的值是矩阵1,1 -> x,y 这个方块的和,所以要求得s,t大小的,只需要减去左边的块,下面的块,多减了他们的交集再加上即可。

 

画个图吧。

 

zoj 1716 || poj 2029 Get Many Persimmon Trees_第1张图片

 

暴力代码

 

#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 102 using namespace std; int map[MAX][MAX]; int main() { int m,w,h,s,t,x,y,i,j,p,k; while( ~scanf("%d",&m) && m ) { memset(map,0,sizeof(map)); scanf("%d%d",&w,&h); while( m-- ) { scanf("%d%d",&x,&y); map[x][y] = 1; } scanf("%d%d",&s,&t); int ans = 0,sum; for(i=1; i<=h-t+1; i++) for(p=1; p<=w-s+1; p++) { sum = 0; for(j=i; j<i+t; j++) for(k=p; k<p+s; k++) sum += map[k][j]; if( sum > ans ) ans = sum; } printf("%d/n",ans); } return 0; }  

 

树状数组

 

#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 105 using namespace std; int c[MAX][MAX]; int w,h; int Lowbit(int x) { return x & (-x); } void Updata( int x,int y) { int i,k; for(i=x; i<MAX; i+=Lowbit(i)) for(k=y; k<MAX; k+=Lowbit(k)) c[i][k]++; } int Getsum(int x,int y) { int i,k,sum = 0; for(i=x; i>0; i-=Lowbit(i)) for(k=y; k>0; k-=Lowbit(k)) sum += c[i][k]; return sum; } int main() { int n,s,t,i,x,y,k; while( ~scanf("%d",&n) && n ) { memset(c,0,sizeof(c)); scanf("%d%d",&w,&h); for(i=0; i<n; i++) { scanf("%d%d",&x,&y); Updata(x,y); } scanf("%d%d",&s,&t); int ans = 0; for(i=s; i<=w; i++) for(k=t; k<=h; k++) { int sum = Getsum(i,k) - Getsum(i-s,k) - Getsum(i,k-t) + Getsum(i-s,k-t); if( sum > ans ) ans = sum; } printf("%d/n",ans); } return 0; }

你可能感兴趣的:(c)