Problem Author: | TheSensei |
Prepared by: | Hasan Saleh (MathModel) |
Edited by: | Hasan Saleh (MathModel) |
Solution
You have an n\times m grid . Define the cost of cell as
i.e. its value times the Manhattan distance to the nearest border. You must answer queries, each giving a subrectangle (l_1,r_1)–(l_2,r_2). Treat that subgrid as a fresh n'\times m' grid (re-indexed from to (n',m')) and compute the sum of its costs.
The weight
depends only on positions (i',j') in the subgrid, not on the original indices. We need \sum A[i][j]\times w_{i',j'} over the rectangle in per query.
Use three prefix-sum structures:
Standard 2D prefix sum
Diagonal prefix
along top-leftbottom-right.
Anti-diagonal prefix
along top-rightbottom-left.
Each subgrid has \left\lfloor\min(n',m')/2\right\rfloor "layers." You can express the total weighted sum as
where each v_k is read off in from the three prefix tables.
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
void solve()
{
ll n,m;
cin>>n>>m;
vector<vector<ll>> num(n+1,vector<ll>(m+1));
for(ll i=1; i<=n; i++) for(ll j=1; j<=m; j++) cin>>num[i][j];
vector<vector<ll>> p(n+1,vector<ll>(m+1,0));
for(ll i=1; i<=n; i++) for(ll j=1; j<=m; j++) p[i][j]=p[i-1][j]+p[i][j-1]-p[i-1][j-1]+num[i][j];
vector<vector<ll>> pd1(n+1,vector<ll>(m+1,0));
for(ll i=1; i<=n; i++) for(ll j=1; j<=m; j++) pd1[i][j]=pd1[i-1][j-1]+p[i][j];
vector<vector<ll>> pd2(n+2,vector<ll>(m+2,0));
for(ll i=1; i<=n; i++) for(ll j=0; j<=m; j++) pd2[i][j]=pd2[i-1][j+1]+p[i][j];
ll q;
cin>>q;
while(q--)
{
ll l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
// to find summation (k varies from 0 to floor(min(l2-l1,r2-r1)/2)) p[l2-k][r2-k]-p[l1-1+k][r2-k]-p[l2-k][r1-1+k]+p[l1-1+k][r1-1+k]
// so, i am seperating the 4 terms, as v1-v2-v3+v4
ll k = min(l2-l1,r2-r1)/2;
ll v1 = pd1[l2][r2]-pd1[max((ll)0,l2-k-1)][max((ll)0,r2-k-1)];
ll v2 = pd2[max((ll)0,l1-1+k)][max((ll)0,r2-k)]-pd2[max((ll)0,l1-2)][max((ll)0,r2+1)];
ll v3 = pd2[l2][r1-1]-pd2[max((ll)0,l2-k-1)][max((ll)0,r1+k)];
ll v4 = pd1[max((ll)0,l1+k-1)][max((ll)0,r1+k-1)]-pd1[max((ll)0,l1-2)][max((ll)0,r1-2)];
ll ans1=v1-v2-v3+v4;
//bruteforce SOLUTION
v1=0;
v2=0;
v3=0;
v4=0;
while(l1<=l2 && r1<=r2)
{
v1+=p[l2][r2];
v2+=p[l1-1][r2];
v3+=p[l2][r1-1];
v4+=p[l1-1][r1-1];
l1++;
r1++;
l2--;
r2--;
}
ll ans2=v1-v2-v3+v4;
cout<<ans1<<"\n";
}
}
int main()
{
IOS;
int t;cin>>t;
while(t--){
solve();
}
}Complexity \mathcal{O}(nm+q)