• bzoj1047


    二维单调队列

    rmq很明显会超时,如果这个序列是一维的,很明显就是个单调队列,现在就是把一维的单调队列转换为二维单调队列。

    先求出每一列的窗口极值,然后对于每一行做单调队列,值就是之前求出每个位置结尾的极值,这样就求出了每个正方形的极值。

    写起来要注意一些。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1010;
    int a, b, n, ans = 1 << 30;
    int d[N][N], mx[N][N], mn[N][N], q1[N], q2[N], mxx[N][N], mnn[N][N];
    int main()
    {
    //  freopen("square.in", "r", stdin);
    //  freopen("square.out", "w", stdout);
        scanf("%d%d%d", &a, &b, &n);
        for(int i = 1; i <= a; ++i)
            for(int j = 1; j <= b; ++j) scanf("%d", &d[i][j]);
        for(int i = 1; i <= a; ++i)
        {
            int l1 = 1, r1 = 0, l2 = 1, r2 = 0;
            for(int j = 1; j <= b; ++j)
            {
                while(l1 <= r1 && j - q1[l1] + 1 > n) ++l1;
                while(l1 <= r1 && d[i][j] > d[i][q1[r1]]) --r1;
                while(l2 <= r2 && j - q2[l2] + 1 > n) ++l2;
                while(l2 <= r2 && d[i][j] < d[i][q2[r2]]) --r2;
                q1[++r1] = j;  
                q2[++r2] = j;
                mx[i][j] = d[i][q1[l1]];
                mn[i][j] = d[i][q2[l2]];    
    //          printf("mx[%d][%d]=%d mn[%d][%d]=%d
    ", i, j, mx[i][j], i, j, mn[i][j]);    
            }
        }
        for(int j = n; j <= b; ++j)
        {
            int l1 = 1, r1 = 0, l2 = 1, r2 = 0;
            for(int i = 1; i <= a; ++i)
            {
                while(l1 <= r1 && i - q1[l1] + 1 > n) ++l1;
                while(l1 <= r1 && mx[i][j] > mx[q1[r1]][j]) --r1;
                while(l2 <= r2 && i - q2[l2] + 1 > n) ++l2;
                while(l2 <= r2 && mn[i][j] < mn[q2[r2]][j]) --r2;
                q1[++r1] = i;
                q2[++r2] = i;
                mxx[i][j] = mx[q1[l1]][j];
                mnn[i][j] = mn[q2[l2]][j];
    //          printf("mxx[%d][%d]=%d mnn[%d][%d]=%d
    ", i, j, mxx[i][j], i, j, mnn[i][j]);
            }
        }
        for(int i = n; i <= a; ++i)
            for(int j = n; j <= b; ++j) ans = min(ans, mxx[i][j] - mnn[i][j]);
        printf("%d
    ", ans);    
    //  fclose(stdin);
    //  fclose(stdout); 
        return 0;
    }
    View Code
  • 相关阅读:
    网上购物瘾,你怎么能退出?
    POJ 1006 Biorhythms 中国的法律来解决剩余的正式
    【Android接口实现】PhotoView——单点支持/多图像缩放,实现了触摸
    线程同步synchronized
    阿里云CentOS 6.5 设备、执行Docker容器和步骤的方法
    打破了中国电信华为无线路由猫(HG522-C)自己主动拨号+任意数量的计算机+iTV
    GCC 命令行具体解释
    Nginx 负载均衡
    Linux pipe功能
    Java有用的经验--Swing片
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7414054.html
Copyright © 2020-2023  润新知