P4514 上帝造题的七分钟 | 二维前缀和板子

# include <bits/stdc++.h>
using namespace std;

const int N = 2050;

int n,m;

int lowbit(int x) {return x & -x;}

struct _2wBIT
{
    int a[N][N];

    void clear(void)
    {
        for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) a[i][j] = 0;
        return;
    }

    void add(int x,int y,int D)
    {
        int lst = y;
        while(x <= n)
        {
            y = lst;
            while(y <= m)
            {
                a[x][y] += D;
                y += lowbit(y);
            }
            x += lowbit(x);
        }
        return;
    }
    int query(int x,int y)
    {
        int ans = 0;
        int lst = y;
        while(x)
        {
            y = lst;
            while(y)
            {
                ans += a[x][y];
                y -= lowbit(y);
            }
            x -= lowbit(x);
        }
        return ans;
    }
}c,d,e,f;

void modify(int x,int y,int D)
{
    c.add(x,y,D);
    d.add(x,y,D * x);
    e.add(x,y,D * y);
    f.add(x,y,D * x * y);
    return;
}

int Ans(int x,int y)
{
    return c.query(x,y) * (x + 1) * (y + 1) - d.query(x,y) * (y + 1) - e.query(x,y) * (x + 1) + f.query(x,y);
}

int main(void)
{
    scanf("X %d%d",&n,&m);
    char opt;
    c.clear(),d.clear(),e.clear(),f.clear();
    int k = 0;
    while(cin >> opt)
    {
        int X1,Y1,X2,Y2,D;
        if(opt == 'L') 
        {
            scanf("%d%d%d%d%d",&X1,&Y1,&X2,&Y2,&D);
            modify(X1,Y1,D);
            modify(X1,Y2 + 1,-D);
            modify(X2 + 1,Y1,-D);
            modify(X2 + 1,Y2 + 1,D);
        }
        else
        {
            scanf("%d%d%d%d",&X1,&Y1,&X2,&Y2);
            printf("%d\n",Ans(X2,Y2) - Ans(X1 - 1,Y2) - Ans(X2,Y1 - 1) + Ans(X1 - 1,Y1 - 1));
        }
    }
    return 0;
}
posted @ 2020-10-31 09:01  luyiming123  阅读(55)  评论(0编辑  收藏  举报