HDU 3531 Match(树状数组)

来源:互联网 发布:淘宝被差评有什么影响 编辑:程序博客网 时间:2024/04/30 14:43

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3531

输入两个0-1矩阵,判断后一个是不是前一个的子矩阵

开始暴力判断,结果超时

后来用树状数组维护枚举区间1的个数,在1的个数相等的情况下来判断是否相等!

#include <string.h>#include <stdio.h>#include <algorithm>#include <iostream>using namespace std;const int maxn = 1005;int first[maxn][maxn],second[maxn][maxn];int tree[maxn][maxn];int n,m;int lowbit(int x){    return (-x)&x;}int update(int i,int j){    int now;    while(i<=n){        now=j;        while(now<=n){            tree[i][now]++;            now+=lowbit(now);        }        i+=lowbit(i);    }    return 0;}int sum(int i,int j){    int ans=0,now;    while(i>0){        now=j;        while(now>0){            ans+=tree[i][now];            now-=lowbit(now);        }        i-=lowbit(i);    }    return ans;}int main(){    int i,j,k,p,q,s;    bool flag;    while(scanf("%d%d",&n,&m)!=EOF){          memset(tree,0,sizeof(tree));          flag=false;          s=0;          for(i=1;i<=n;i++)          for(j=1;j<=n;j++){              scanf("%d",&first[i][j]);              if(first[i][j]) update(i,j);          }          for(i=1;i<=m;i++)          for(j=1;j<=m;j++){              scanf("%d",&second[i][j]);              s+=second[i][j];          }          if(n<m){              printf("No\n");              continue;          }          k=n-m+2;          for(i=1;i<k;i++)          for(j=1;j<k;j++){              if(sum(i+m-1,j+m-1)-sum(i-1,j+m-1)-sum(i+m-1,j-1)+sum(i-1,j-1) != s)              continue;              for(p=1;p<=m;p++)              for(q=1;q<=m;q++){                  if(first[i+p-1][j+q-1]!=second[p][q])                  p=m+2,q=m+2;//printf("OO");              }              //              if(p!=m+3 && q!=m+3) flag=true,i=k,j=k;          }          if(flag){              printf("Yes\n");          }else{              printf("No\n");          }    }    return 0;}