zoukankan      html  css  js  c++  java
  • Luogu 4514 上帝造题的七分钟

    二维差分+树状数组。

    定义差分数组$d_{i, j} = a_{i, j} + a_{i - 1, j - 1} - a_{i, j - 1} - a_{i - 1, j}$,有$a_{i, j} = sum_{x = 1}^{i}sum_{y = 1}^{j}d_{i, j}$。

    我们要求$sum(n, m) = sum_{i = 1}^{n}sum_{j = 1}^{m}a_{i, j} $,

    代入$a_{i, j}$,得$sum(n, m) = sum_{i = 1}^{n}sum_{j = 1}^{m}sum_{x = 1}^{i}sum_{y = 1}^{j}d_{x, y}$。

    列一下发现$d_{x, y}$出现了$(n - x + 1) * (m - y + 1)$次。

    那么$sum(n, m) = sum_{i = 1}^{n}sum_{j = 1}^{m}d_{i, j} * (n - i + 1) * (m - j + 1)$。

    把$(n + 1),(m + 1),i, j$看作四项展开,得到$(n + 1) * (m + 1)sum_{i = 1}^{n}sum_{j = 1}^{m}d_{i, j} + sum_{i = 1}^{n}sum_{j = 1}^{m}d_{i, j} * i * j - (m + 1)  sum_{i = 1}^{n}sum_{j = 1}^{m}d_{i, j} * i - (n + 1)sum_{i = 1}^{n}sum_{j = 1}^{m}d_{i, j} * j$。

    两个$sum$可以用一个二维树状数组维护,这样子维护四个树状数组即可(修改好长)

    时间复杂度$O(qlognlogm)$。

    另外,longlong在Luogu上会MLE最后两个点,要用int

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef int ll;
    
    const int N = 2050;
    
    int n, m;
    
    template <typename T>
    inline void read(T &X) {
        X = 0; char ch = 0; T op = 1;
        for(; ch > '9'|| ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    struct BinaryIndexTree {
        ll arr[N][N];
        
        #define lowbit(p) (p & (-p))
        
        inline void modify(int x, int y, ll v) {
            for(int i = x; i <= n; i += lowbit(i))
                for(int j = y; j <= m; j += lowbit(j))
                    arr[i][j] += v;
        }
        
        inline ll query(int x, int y) {
            ll res = 0LL;
            for(int i = x; i > 0; i -= lowbit(i))
                for(int j = y; j > 0; j -= lowbit(j))
                    res += arr[i][j];
            return res;
        }
        
    } sum, mulij, muli, mulj;
    
    inline int min(int x, int y) {
        return x > y ? y : x;
    }
    
    inline int max(int x, int y) {
        return x > y ? x : y;
    }
    
    inline ll qSum(int x, int y) {
        return 1LL * (x + 1) * (y + 1) * sum.query(x, y) + 1LL * mulij.query(x, y) 
            - 1LL * (y + 1) * muli.query(x, y) - 1LL * (x + 1) * mulj.query(x, y);
    }
    
    int main() {
    //    freopen("Sample.txt", "r", stdin);
        
        char op = getchar();
        read(n), read(m);
        for(; ; ) {
            for(op = getchar(); op != 'L' && op != 'k' && op >= 0; op = getchar());
            if(op < 0) break;
            
            if(op == 'L') {
                int a, b, c, d; ll v;
                read(a), read(b), read(c), read(d), read(v);
                int lx = min(a, c), ly = min(b, d), rx = max(a, c), ry = max(b, d);
                sum.modify(lx, ly, v);
                sum.modify(rx + 1, ry + 1, v);
                sum.modify(lx, ry + 1, -v);
                sum.modify(rx + 1, ly, -v);
                
                muli.modify(lx, ly, v * lx);
                muli.modify(rx + 1, ry + 1, v * (rx + 1));
                muli.modify(lx, ry + 1, -v * lx);
                muli.modify(rx + 1, ly, -v * (rx + 1));
    
                mulj.modify(lx, ly, v * ly);
                mulj.modify(rx + 1, ry + 1, v * (ry + 1));
                mulj.modify(lx, ry + 1, -v * (ry + 1));
                mulj.modify(rx + 1, ly, -v * ly);
                
                mulij.modify(lx, ly, v * lx * ly);
                mulij.modify(rx + 1, ry + 1, v * (rx + 1) * (ry + 1));
                mulij.modify(lx, ry + 1, -v * (ry + 1) * lx);
                mulij.modify(rx + 1, ly, -v * (rx + 1) * ly);
            } else {
                int a, b, c, d;
                read(a), read(b), read(c), read(d);
                int lx = min(a, c), ly = min(b, d), rx = max(a, c), ry = max(b, d);
                printf("%d
    ", qSum(rx, ry) + qSum(lx - 1, ly - 1) - qSum(rx, ly - 1) - qSum(lx - 1, ry));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    2011年微软全球Next大赛闭幕。一站式示例代码库等30个项目获Microsoft Next殊荣
    微软一站式示例代码库(中文版)20110513版本, 新添加Windows Azure, WinForms等16个Sample
    发布:Visual Studio 2010 一站式示例代码搜索扩展
    微软一站式示例代码库 中文介绍视频发布 翻译得很幽默哦!
    六月新版微软一站式示例代码库发布 新增20个Windows示例代码
    Winform中使用打开文件对话框和文件夹浏览对话框
    二分查找
    求2个集合的交集
    自定义html代码运行框
    Winform中使用进度条的一个例子
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9618627.html
Copyright © 2011-2022 走看看