• Luogu P4514 上帝造题的七分钟 (二维树状数组模板)


    gate

    二维树状数组,区间修改,区间查询

    对于区间$(x,y)$,用差分数组来维护,每次从$(1,1)$加到$(i,j)$

    可以发现,$t[1][1]$被加了$x*y$次,$t[1][2]$被加了$(x-1)*y$次…

    那么区间$(x,y)$的和即为

    $∑i=(1,x)∑j=(1,y)$ $t[i][j]*(x-i+1)*(y-j+1)$

    把括号打开

    $∑i=(1,x)∑j=(1,y)$ $t[i][j]*(x+1)*(y+1) + t[i][j]*i*(y+1) + t[i][j]*j*(x+1) + t[i][j]*i*j$

    所以维护四个数组,分别表示:$t[i][j],t[i][j]*i,t[i][j]*j,t[i][j]*i*j$

    然后查询的时候,乘上对应的$x+1$和$y+1$。

    修改一段区间$(x_1-x_2,y_1-y_2)$时,则有

    $+(x_1,y_2),-(x_2+1,y_1),-(x_1,y_2+1),+(x_2+1,y_2+1)$

    查询一段区间$(x_1-x_2,y_1-y_2)$时,则有

    $+(x_1-1,y_2-1),-(x_2,y_1-1),-(x_1-1,y_2),+(x_2,y_2)$

    代码如下...

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define MogeKo qwq
    using namespace std;
    
    int n,m,a,b,c,d,k;
    int t[5][2050][2050];
    char op;
    
    int read() {
        int x = 0,f = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9') {
            if(ch == '-') f = -1;
            ch = getchar();
        }
        while('0' <= ch && ch <= '9') {
            x = (x<<3)+(x<<1) + ch-'0';
            ch = getchar();
        }
        return x * f;
    }
    
    int lowbit(int x) {
        return x & (-x);
    }
    
    void update(int x,int y,int k) {
        for(int i = x; i <= n; i += lowbit(i))
            for(int j = y; j <= m; j += lowbit(j)) {
                t[1][i][j] += k;
                t[2][i][j] += k * x;
                t[3][i][j] += k * y;
                t[4][i][j] += k * x * y;
            }
    }
    
    int query(int x,int y) {
        int ret = 0;
        for(int i = x; i; i -= lowbit(i))
            for(int j = y; j; j -= lowbit(j)) {
                ret += t[1][i][j] * (x+1) * (y+1);
                ret -= t[2][i][j] * (y+1);
                ret -= t[3][i][j] * (x+1);
                ret += t[4][i][j];
            }
        return ret;
    }
    
    void getupdate(int a,int b,int c,int d,int k) {
        update(c+1,d+1,k);
        update(c+1,b,-k);
        update(a,d+1,-k);
        update(a,b,k);
    }
    
    int getquery(int a,int b,int c,int d) {
        return query(c,d) - query(c,b-1) - query(a-1,d) + query(a-1,b-1);
    }
    
    int main() {
        scanf("%c%d%d",&op,&n,&m);
        while(cin >> op) {
            a = read(),b = read(),c = read(),d = read();
            if(op == 'L') {
                k = read();
                getupdate(a,b,c,d,k);
            }
            if(op == 'k')
                printf("%d
    ",getquery(a,b,c,d));
        }
        return 0;
    }
  • 相关阅读:
    Java实现埃拉托色尼筛选法
    Java实现希尔排序
    Java实现希尔排序
    Java实现希尔排序
    Java实现希尔排序
    Java实现希尔排序
    Java实现插入排序
    Java实现插入排序
    Java实现插入排序
    使用Qt5.7.0 VS2015版本生成兼容XP的可执行程序 good(从VS2012 update1开始支持xp和c++11)
  • 原文地址:https://www.cnblogs.com/mogeko/p/11842984.html
Copyright © 2020-2023  润新知