> 文档中心 > 牛牛的方格图 (二维差分)

牛牛的方格图 (二维差分)

牛牛:“你喜欢玩数独吗?”。

牛牛有一个

方格图,每个格子都有自己的颜色,第 行第 列格子上的颜色记为 。

对于任意两个不同位置的颜色相同的点,我们认为其覆盖了一个以它们为对角线上顶点的矩形中的所有点。

现在牛牛想知道这张方格图中有多少个顶点尚未被覆盖。

 题解:

根据你遍历的顺序差分一下就行了。

#include#include#include#include#includeusing namespace std;int n,m,d[1005][1005];vector<pair > v[1000005];int main(){    scanf("%d%d",&n,&m);    int x;    for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){     scanf("%d",&x);     v[x].push_back({i,j}); }    }    for(int i=1;i<=1000000;i++){ if(v[i].size()<=1) continue; int mxx=0,mnx=1e9,mxy=0,mny=1e9; for(auto vv:v[i]){     mxx=max(mxx,vv.first);     mnx=min(mnx,vv.first);     mxy=max(mxy,vv.second);     mny=min(mny,vv.second); } // printf("%d %d %d %d\n",mnx,mxx,mny,mxy); d[mnx][mny]+=1; d[mnx][mxy+1]-=1; d[mxx+1][mxy+1]+=1; d[mxx+1][mny]-=1;    }    int ans=0;    for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){     d[i][j]+=d[i-1][j]+d[i][j-1]-d[i-1][j-1];     if(!d[i][j]) ++ans;     // printf("%3d",d[i][j]); } // puts("");    }    printf("%d\n",ans);    return 0;}