D - Count Subgrid Sum = K 解説 by en_translator
Let us aim at solving the problem in \(O(W)\) time when the top ant bottom rows of the rectangular region is fixed, so that the entire problem can be solved in a total of \(O(H^2W)\).
Fix the top and bottom rows. Let \(A_j\) be the sum of column \(j\), and \(B_j=A_1+A_2+\dots+A_j\). With an appropriate precalculation, these can be found in \(O(W)\) time.
\(B_r-B_l\) equals the sum of the integers written in the rectangular region in rows \((l+1)\) through \(r\), so we want to find the number of pairs \((l,r)\) with \(B_r-B_l = K\) and \(0 \le l < r \le W\) (where we define \(B_0=0\)).
We apply the following idea to reduce the complexity: count the number of pairs with \(B_r-B_l \ge K\) and the number with \(B_r-B_l > K\), and find their difference.
Since \(A_j \ge 0\) for all \(j\), \(B\) is (weakly) monotonically increasing, so for both problems, as \(l\) increases the minimum possible \(r\) also (weakly) monotonically increases. We also see that any integers between that \(r\) and \(W\) is valid.
Thus, both problems can be solved with the sliding window trick. Each sliding-window scan costs \(O(W)\) time.
The time complexity is \(O(H^2W)\).
Sample code (C++):
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll subp(vector<ll> &a,ll k){
ll n=a.size();
ll r1=0,r2=0,res=0;
for(ll l=0;l+1<n;l++){
r1=max(r1,l+1); r2=max(r2,l+1);
while(r1<n && a[r1]-a[l]<k){r1++;}
while(r2<n && a[r2]-a[l]<=k){r2++;}
res+=(r2-r1);
}
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long h,w,k;
cin >> h >> w >> k;
vector<vector<ll>> a(h+1,vector<ll>(w+1,0));
for(ll i=1;i<=h;i++){
string s;
cin >> s;
for(ll j=1;j<=w;j++){
if(s[j-1]=='1'){a[i][j]=1;}
}
}
for(ll i=1;i<=h;i++){
for(ll j=1;j<=w;j++){
a[i][j]+=a[i-1][j];
}
}
ll res=0;
for(ll u=1;u<=h;u++){
for(ll d=u;d<=h;d++){
vector<ll> b(w+1,0);
for(ll j=1;j<=w;j++){
b[j]=b[j-1]+(a[d][j]-a[u-1][j]);
}
res+=subp(b,k);
}
}
cout << res << "\n";
return 0;
}
投稿日時:
最終更新: