zoukankan      html  css  js  c++  java
  • Gym

    De Prezer loves rectangles.He has a n × m rectangle which there is a number in each of its cells. We show the number in the j - th column of the i - th row by ai, j.

    De Prezer also loves query. So he gives you q queries. In each query, he gives you number k and asks you to print the number of subrectangles of this rectangle that the difference between the maximum element and the minimum element in them is at most k .

    Input

    The first line of input contains 3 integers, nm and q .

    In the next n lines, there are informations of the rectangle. i - th line among them, contains m space separated integers, ai, 1, ai, 2, ..., ai, m .

    The next q lines, each line contains a single integer k (for that query).

    1 ≤ n, m ≤ 400

    1 ≤ q ≤ 10

    1 ≤ ai, j ≤ 109 (for each 1 ≤ i ≤ n and 1 ≤ j ≤ m)

    0 ≤ k ≤ 109 (for each query)

    Output

    For each query, print the answer in a single line.

    Examples

    Input
    5 4 6
    451 451 452 452
    452 452 452 452
    451 452 450 450
    451 451 451 451
    452 452 450 450
    0
    2
    773726
    724963313
    1
    1
    Output
    42
    150
    150
    150
    88
    88
    Input
    4 5 8
    1314 1287 1286 1290 1295
    1278 1271 1324 1317 1289
    1305 1305 1284 1300 1309
    1318 1296 1301 1274 1315
    976296835
    12
    13
    38
    16
    40
    665711658
    35
    Output
    150
    34
    35
    82
    37
    92
    150
    77

    题意:给定矩阵,问有多少个非空子矩阵满足矩阵中最大值-最小值<=K。

    思路:不难想到要压缩矩阵,即枚举枚举矩阵的上边界和下边界,然后压缩,看成一维的,如果可以线性解决一维的,则单次询问的复杂度为O(N^2*M)。

    那么现在给定数组a[],我们用一个单增队列保存最小值的位置,用一个单减队列保存最大值的位置。对于R,如果二队首对应的值之差>K,则L++,并且维护队首>=L;

    (主要是两个单调队列,我们移动的不是队首,而且L,在L>队首时,弹出队首。妙啊。VJ一血?

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++) 
    #define ll long long
    using namespace std;
    const int maxn=401;
    const int inf=1<<30;
    int a[maxn][maxn],Mx[maxn],Mn[maxn],q[maxn][2],N,M,Q;
    void solve(int K)
    {
        ll res=0;
        rep(i,1,N){
            rep(p,1,M) Mx[p]=-inf,Mn[p]=inf;
            rep(j,i,N){
                rep(p,1,M) Mx[p]=max(Mx[p],a[j][p]);
                rep(p,1,M) Mn[p]=min(Mn[p],a[j][p]);
                 int l=1,h0=0,t0=1,h1=0,t1=1;
                 rep(r,1,M){
                     while(t0<=h0&&Mx[r]>=Mx[q[h0][0]]) h0--;
                     while(t1<=h1&&Mn[r]<=Mn[q[h1][1]]) h1--;
                     q[++h0][0]=r; q[++h1][1]=r;
                     while(l<=r&&Mx[q[t0][0]]-Mn[q[t1][1]]>K){
                         l++; //移动得很巧妙。 
                         if(q[t0][0]<l) t0++;
                         if(q[t1][1]<l) t1++;
                    }
                    res+=r-l+1;
                }
            }
        }
        printf("%I64d
    ",res);
    }
    int main()
    {
        scanf("%d%d%d",&N,&M,&Q);
        rep(i,1,N) rep(j,1,M) scanf("%d",&a[i][j]);
        while(Q--){
            int k; scanf("%d",&k);
            solve(k);
        }
        return 0;
    }
  • 相关阅读:
    我的博客园的博客开通啦
    设置cookie
    JavaScript自动提示
    补码
    vim快捷键
    JavaScript获取URL参数
    Linux根目录下子目录的功能
    JavaScript分页栏链接转变算法
    可输可选可自动提示,还可增加一个!
    VS2008启动调试,出现“ 已经找到网站 正在等待回应”
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9509760.html
Copyright © 2011-2022 走看看