E - Grid Filling Editorial by llichenyu


English:

We can use queues to easily solve this problem.

Assuming that we are at position \((x,y)\).

If we want to find the answer on \((x,y+1)\) in \(O(n)\) time,What should we do?

Simply,we only need to delete the positions \((i,y)\) and add the positions \((i+h,y)\) while \( x \le i \le x+h-1\).

So we have successfully solved it!

Chinese:

我们可以用队列来解决这个问题。

假设我们当前处在 \((x,y)\),考虑如何转移到 \((x,y+1)\)

我们发现我们可以直接删去 \((i,y)\) 的贡献,加上 \((i+h,y)\) 的贡献,其中 \(x \le i \le x+h-1\)

然后我们就解决这个问题了!

Code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int const N=300+10;
int a[N][N],ans[N][N];
map< int,int >mp,mp1;
int now=0;
inline void add(int x){
    ++mp1[x];
    now-=(mp1[x]==mp[x]);
}
inline void del(int x){
    now+=(mp1[x]==mp[x]);
    --mp1[x];
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int hh,ww,nn,h,w;cin>>hh>>ww>>nn>>h>>w;
    int res=0;
    for (int i=1;i<=hh;++i)
        for (int j=1;j<=ww;++j)
            cin>>a[i][j],res+=(!mp[a[i][j]]),++mp[a[i][j]];
    for (int i=1;i<=hh-h+1;++i){
        mp1.clear();now=res;
        for (int k=i;k<=i+h-1;++k)
            for (int j=1;j<=w;++j)
                add(a[k][j]);
        ans[i][1]=now;
        for (int j=1;j<=ww-w;++j){
            for (int k=i;k<=i+h-1;++k)
                del(a[k][j]),add(a[k][j+w]);
            ans[i][j+1]=now;
        }
    }
    for (int i=1;i<=hh-h+1;++i){
        for (int j=1;j<=ww-w+1;++j)
            cout<<ans[i][j]<<' ';
        cout<<'\n';
    }
    return 0;
}

posted:
last update: