D - Monitor HDU - 6514 (二维前缀和差分处理)
题目链接:
D - Monitor
题目大意:给你一个n*m的矩阵,然后在这个n*m的矩阵中有q个子矩阵被覆盖,然后q次询问,问你当前询问的子矩阵是不是被完全覆盖。
具体思路: 首先n和m不知道多大,我们可以把矩阵转换成点进行计算(i-1)*m+j.然后就是二维前缀和的处理了。
具体处理的时候是从下往上更新的,具体的端点赋值大体推理一遍就好了。
https://blog.csdn.net/K_R_forever/article/details/81775899
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 2e7+100; 5 const int N = 1000+10; 6 int n,m,q; 7 int x1,y1,x2,y2; 8 int a[maxn]; 9 int get_id(int x,int y) 10 { 11 if(x<1||x>n||y>m)// 注意边界 12 return 0; 13 return (x-1)*m+y; 14 } 15 int ask(int x,int y) 16 { 17 return a[get_id(x,y)]; 18 } 19 int main() 20 { 21 while(~scanf("%d %d",&n,&m)) 22 { 23 for(int i=0; i<=n*m; i++) 24 a[i]=0; 25 scanf("%d",&q); 26 while(q--) 27 { 28 scanf("%d %d %d %d",&x1,&y1,&x2,&y2); 29 a[get_id(x1,y1)]++; 30 a[get_id(x2+1,y1)]--; 31 a[get_id(x1,y2+1)]--; 32 a[get_id(x2+1,y2+1)]++; 33 } 34 for(int i=1; i<=n; i++) 35 { 36 for(int j=1; j<=m; j++) 37 { 38 a[get_id(i,j)]=ask(i,j)+ask(i-1,j)+ask(i,j-1)-ask(i-1,j-1);// 差分数组顺序更新 39 } 40 } 41 for(int i=1; i<=n; i++) 42 { 43 for(int j=1; j<=m; j++) 44 { 45 a[get_id(i,j)]=a[get_id(i,j)]>0?1:0;// 如果当前点被覆盖,那么就覆盖为1 46 } 47 } 48 for(int i=1; i<=n; i++) 49 { 50 for(int j=1; j<=m; j++) 51 { 52 a[get_id(i,j)]+=ask(i-1,j)+ask(i,j-1)-ask(i-1,j-1);// 判断当前点到(0,0)形成的面积 53 } 54 } 55 scanf("%d",&q); 56 while(q--) 57 { 58 scanf("%d %d %d %d",&x1,&y1,&x2,&y2); 59 int tmp=ask(x2,y2)-ask(x1-1,y2)-ask(x2,y1-1)+ask(x1-1,y1-1); 60 if(tmp==(x2-x1+1)*(y2-y1+1)) 61 printf("YES\n"); 62 else 63 printf("NO\n"); 64 } 65 } 66 return 0; 67 }