• 容斥 或者 单调栈 hihocoder #1476 : 矩形计数 和 G. Snake Rana 2017 ACM Arabella Collegiate Programming Contest


    先说一个简单的题目(题目大意自己看去,反正中文):hihocoder上的:http://hihocoder.com/problemset/problem/1476

    然后因为这个n和m的矩阵范围是1000,所以比较简单

    然后我们说一下hihocoder上面的做法,首先,这题的做法是http://www.cnblogs.com/heimao5027/p/6738715.html的简化版本,因为颜色只有两种,所以和前面链接给的做法那样,用单调栈维护一下即可。

    //看看会不会爆int!数组会不会少了一维!
    //取物问题一定要小心先手胜利的条件
    #include <bits/stdc++.h>
    using namespace std;
    #pragma comment(linker,"/STACK:102400000,102400000")
    #define LL long long
    #define ALL(a) a.begin(), a.end()
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define haha printf("haha
    ")
    const int maxn = 1000 + 5;
    int n, m, k;
    map<pair<int, int>, int> mp;
    int color[maxn][maxn], h[maxn][maxn];
    LL dp[maxn][maxn];
    
    struct Point{
        int high, col;
    };
    
    int main(){
        scanf("%d%d%d", &n, &m, &k);
        for (int i = 1; i <= k; i++){
            int a, b; scanf("%d%d", &a, &b);
            mp[mk(a, b)] = 1;
            color[a][b] = 1;
        }
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= m; j++){
                dp[i][j] = 0;
                h[i][j] = 0;
                if (color[i][j]) continue;
                h[i][j] = 1;
                if (color[i][j] == color[i - 1][j])
                    h[i][j] += h[i - 1][j];
            }
        }
        LL ans = 0;
        for (int i = 1; i <= n; i++){
            stack<Point> stc;
            for (int j = 1; j <= m; j++){
                if (color[i][j] == 1){
                    while (!stc.empty()) stc.pop();
                    continue;
                }
                int lb = j;
                while (!stc.empty()){
                    if (stc.top().high >= h[i][j]) {
                        lb = stc.top().col; stc.pop();
                    }
                    else break;
                }
                dp[i][j] += 1LL * h[i][j] * (j - lb + 1);
                //printf("h[%d][%d] = %d lb = %d add = %lld
    ", i, j, h[i][j], lb, 1LL*h[i][j] * (j - lb + 1));
                stc.push(Point{h[i][j], lb});
                if (color[i][lb - 1] == 0) dp[i][j] += dp[i][lb - 1];
                ans += dp[i][j];
            }
        }
        cout << ans << endl;
        return 0;
    }
    View Code

    对于GYM上的题目:http://codeforces.com/gym/101350/problem/G

    这题的n和m的范围是10000,所以很难用这个方法,因为对于1e8,空间是绝对开不下的

  • 相关阅读:
    技术面试之经验总结
    为何只有两篇文章?
    LOJ6364 烂柯
    mysql批量更新数据(性能优化)
    一个对象的key引发的血案
    总结与元素坐标相关的属性(再也搞不混了)
    利用nodejs搭建服务器,测试AJAX
    初探jquery之强大丰富的选择器
    Web前端开发规范手册
    IE8下标签float导致的bug。
  • 原文地址:https://www.cnblogs.com/heimao5027/p/6828139.html
Copyright © 2020-2023  润新知