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: