H. Hard Demon Problem

H. Hard Demon Problem

Swing is opening a pancake factory! A good pancake factory must be good at flattening things, so Swing is going to test his new equipment on 2D matrices.

Swing is given an $n \times n$ matrix $M$ containing positive integers. He has $q$ queries to ask you.

For each query, he gives you four integers $x_1$, $y_1$, $x_2$, $y_2$ and asks you to flatten the submatrix bounded by $(x_1, y_1)$ and $(x_2, y_2)$ into an array $A$. Formally, $A = [M_{(x1,y1)}, M_{(x1,y1+1)}, \ldots, M_{(x1,y2)}, M_{(x1+1,y1)}, M_{(x1+1,y1+1)}, \ldots, M_{(x2,y2)}]$.

The following image depicts the flattening of a submatrix bounded by the red dotted lines. The orange arrows denote the direction that the elements of the submatrix are appended to the back of $A$, and $A$ is shown at the bottom of the image.

Afterwards, he asks you for the value of $\sum_{i=1}^{|A|} A_i \cdot i$ (sum of $A_i \cdot i$ over all $i$).

Input

The first line contains an integer $t$ ($1 \leq t \leq 10^3$) — the number of test cases.

The first line of each test contains two integers $n$ and $q$ ($1 \leq n \leq 2000, 1 \leq q \leq 10^6$) — the length of $M$ and the number of queries.

The following $n$ lines contain $n$ integers each, the $i$'th of which contains $M_{(i,1)}, M_{(i,2)}, \ldots, M_{(i,n)}$ ($1 \leq M_{(i, j)} \leq 10^6$).

The following $q$ lines contain four integers $x_1$, $y_1$, $x_2$, and $y_2$ ($1 \leq x_1 \leq x_2 \leq n, 1 \leq y_1 \leq y_2 \leq n$) — the bounds of the query.

It is guaranteed that the sum of $n$ over all test cases does not exceed $2000$ and the sum of $q$ over all test cases does not exceed $10^6$.

Output

For each test case, output the results of the $q$ queries on a new line.

Example

Input

2
4 3
1 5 2 4
4 9 5 3
4 5 2 3
1 5 5 2
1 1 4 4
2 2 3 3
1 2 4 3
3 3
1 2 3
4 5 6
7 8 9
1 1 1 3
1 3 3 3
2 2 2 2

Output

500 42 168 
14 42 5 

Note

In the second query of the first test case, $A = [9, 5, 5, 2]$. Therefore, the sum is $1 \cdot 9 + 2 \cdot 5 + 3 \cdot 5 + 4 \cdot 2 = 42$.

 

解题思路

  纯粹就是把累加转换成前缀和的表示形式然后推式子,关键是需要维护前缀和很多,且式子很复杂易推错。

  先从简单的情况考虑,假设询问的是某一行,即 $x_1 = x_2 = i$,此时的结果为
$$
\begin{align*}
&\sum\limits_{j=y_1}^{y_2}{(j-y_1+1)a_{i,j}} \\
=& \, (1-y_1)\sum\limits_{j=y_1}^{y_2}{a_{i,j}} + \sum\limits_{j=y_1}^{y_2}{j \cdot a_{i,j}}
\end{align*}
$$

  记 $\dot{r}_{i,j} = \sum\limits_{k=1}^{j}{a_{i,k}}$,$\ddot{r}_{i,j} = \sum\limits_{k=1}^{j}{k \cdot a_{i,k}}$,则有
$$
\begin{align*}
& \, (1-y_1)\sum\limits_{j=y_1}^{y_2}{a_{i,j}} + \sum\limits_{j=y_1}^{y_2}{j \cdot a_{i,j}} \\
=& \, (1-y_1)(\dot{r}_{i,y_2} - \dot{r}_{i,y_1-1}) + \ddot{r}_{i,y_2} - \ddot{r}_{i,y_1-1}
\end{align*}
$$

  现在考虑询问多行的情况,对于每一行,其实只需在上述结果的基础上再加上 $(i-x_1)(y_2-y_1+1)\sum\limits_{j=y_1}^{y_2}{a_{i,j}}$,以保证该行每个元素乘以的系数是正确的。

$$
\begin{align*}
&\sum\limits_{i=x_1}^{x_2} (1-y_1)(\dot{r}_{i,y_2} - \dot{r}_{i,y_1-1}) + \ddot{r}_{i,y_2} - \ddot{r}_{i,y_1-1} + (i-x_1)(y_2-y_1+1)\sum\limits_{j=y_1}^{y_2}{a_{i,j}} \\
=& \sum\limits_{i=x_1}^{x_2} (1-y_1)(\dot{r}_{i,y_2} - \dot{r}_{i,y_1-1}) + \ddot{r}_{i,y_2} - \ddot{r}_{i,y_1-1} + (i-x_1)(y_2-y_1+1)(\dot{r}_{i,y_2} - \dot{r}_{i,y_1-1}) \\
=& \, (y_2-y_1+1)\sum\limits_{i=x_1}^{x_2}{i \cdot \dot{r}_{i,y_2} - i \cdot \dot{r}_{i,y_1-1}} \\ &+(1-y_1-x_1(y_2-y_1+1))\sum\limits_{i=x_1}^{x_2}{\dot{r}_{i,y_2} - \dot{r}_{i,y_1-1}} \\ &+ \sum\limits_{i=x_1}^{x_2}{\ddot{r}_{i,y_2} - \ddot{r}_{i,y_1-1}}
\end{align*}
$$

  记 $\dot{c}_{i,j} = \sum\limits_{k=1}^{i}{\dot{r}_{k,j}}$,$\ddot{c}_{i,j} = \sum\limits_{k=1}^{i}{\ddot{r}_{k,j}}$,$\dddot{c}_{i,j} = \sum\limits_{k=1}^{i}{k \cdot\dot{r}_{k,j}}$,则有
$$
\begin{align*}
& \, (y_2-y_1+1)\sum\limits_{i=x_1}^{x_2}{i \cdot \dot{r}_{i,y_2} - i \cdot \dot{r}_{i,y_1-1}} \\ &+ (1-y_1-x_1(y_2-y_1+1))\sum\limits_{i=x_1}^{x_2}{\dot{r}_{i,y_2} - \dot{r}_{i,y_1-1}} \\ &+ \sum\limits_{i=x_1}^{x_2}{\ddot{r}_{i,y_2} - \ddot{r}_{i,y_1-1}} \\
=& \, (y_2-y_1+1)(\dddot{c}_{x_2,y_2} - \dddot{c}_{x_1-1,y_2} - (\dddot{c}_{x_2,y_1-1} - \dddot{c}_{x_1-1,y_1-1})) \\ &+ (1-y_1-x_1(y_2-y_1+1))(\dot{c}_{x_2,y_2} - \dot{c}_{x_1-1,y_2} - (\dot{c}_{x_2,y_1-1} - \dot{c}_{x_1-1,y_1-1})) \\ &+ \ddot{c}_{x_2,y_2} - \ddot{c}_{x_1-1,y_2} - (\ddot{c}_{x_2,y_1-1} - \ddot{c}_{x_1-1,y_1-1})
\end{align*}
$$
  记 $f(c) = c_{x_2,y_2} - c_{x_1-1,y_2} - (c_{x_2,y_1-1} - c_{x_1-1,y_1-1})$,则有
$$
\begin{align*}
& \, (y_2-y_1+1)(\dddot{c}_{x_2,y_2} - \dddot{c}_{x_1-1,y_2} - (\dddot{c}_{x_2,y_1-1} - \dddot{c}_{x_1-1,y_1})) \\ &+ (1-y_1-x_1(y_2-y_1+1))(\dot{c}_{x_2,y_2} - \dot{c}_{x_1-1,y_2} - (\dot{c}_{x_2,y_1-1} - \dot{c}_{x_1-1,y_1})) \\ &+ \ddot{c}_{x_2,y_2} - \ddot{c}_{x_1-1,y_2} - (\ddot{c}_{x_2,y_1-1} - \ddot{c}_{x_1-1,y_1}) \\
=& \, (y_2-y_1+1)f(\dddot{c}) + (1-y_1-x_1(y_2-y_1+1))f(\dot{c}) + f(\ddot{c})
\end{align*}
$$
  AC 代码如下,时间复杂度为 $O(n^2 + q)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2005;

LL r1[N][N], r2[N][N], c1[N][N], c2[N][N], c3[N][N];

void solve() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            int x;
            cin >> x;
            r1[i][j] = r1[i][j - 1] + x;
            r2[i][j] = r2[i][j - 1] + j * x;
        }
    }
    for (int j = 1; j <= n; j++) {
        for (int i = 1; i <= n; i++) {
            c1[i][j] = c1[i - 1][j] + r1[i][j];
            c2[i][j] = c2[i - 1][j] + r2[i][j];
            c3[i][j] = c3[i - 1][j] + i * r1[i][j];
        }
    }
    while (m--) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        auto f = [&](LL c[][N]) {
            return c[x2][y2] - c[x1 - 1][y2] - c[x2][y1 - 1] + c[x1 - 1][y1 - 1];
        };
        cout << (y2 - y1 + 1) * f(c3) + (1 - y1 - x1 * (y2 - y1 + 1)) * f(c1) + f(c2) << ' ';
    }
    cout << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 993 (Div. 4) Editorial:https://codeforces.com/blog/entry/137306

posted @ 2024-12-19 09:31  onlyblues  阅读(8)  评论(0编辑  收藏  举报
Web Analytics