See you~(二维树状数组)

来源:互联网 发布:java权限管理表设计 编辑:程序博客网 时间:2024/06/10 21:47

这里写图片描述
See you~
题目链接 (http://acm.hdu.edu.cn/showproblem.php?pid=1892)

这道题就是直接套了一个二维树状数组的模板
不过值得注意的是 树状数组都是下标从一开始的
而这里是下标从0开始的 所以需要先自增然后在进行运算
还有一点就是如何算矩阵
可以看出如果我们想算红色的区域的大小
需要用sum(c,d)(红色 + 蓝色 + 黄色 + 绿色) - sum(a-1,d)(黄色+ 绿色) - sum(c,b-1)(蓝色 + 绿色) + sum(a-1,b-1)(绿色)

#include<iostream>#include<string.h>#include<stdio.h>#include<algorithm>using namespace std;int c[1008][1008],a[1008][1008];//c数组存储的是i行j列矩阵所包含的数量 a数组 所表示的意义是 i 行j列的书的个数int lowbit(int x){    return x&(-x);}void change(int x,int y,int num){    a[x][y] +=num;    for(int i = x; i <= 1008; i += lowbit(i))        for(int j = y; j <= 1008; j += lowbit(j))            c[i][j] += num;}int getsum(int x,int y){    int tot = 0;    for(int i = x; i > 0; i -= lowbit(i))        for(int j = y; j > 0; j -= lowbit(j))            tot += c[i][j];    return tot;}void init(){    memset(c,0,sizeof(c));    memset(a,0,sizeof(a));    for(int i =1;i<1007;i++)    {        for(int j = 1;j<1007;j++)            change(i,j,1);    }}int main(){   int T, n, x1, x2, y1, y2, n1;    char cmd[3];    scanf("%d", &T);    for(int cnt = 1; cnt <= T; ++cnt)    {        init();        scanf("%d", &n);        printf("Case %d:\n", cnt);        while(n--)        {            scanf("%s", cmd);            if(cmd[0] == 'A')            {                scanf("%d%d%d", &x1, &y1, &n1);                //树状数组下标从1开始 而题目中下标从0开始 故需要自增                change(x1+1, y1+1, n1);            }            else if(cmd[0] == 'S')            {                scanf("%d%d%d%d", &x1, &y1, &x2, &y2);                ++x1;                ++x2;                ++y1;                ++y2;                if(x1 > x2)//这是求对角线                    swap(x1, x2);                if(y1 > y2)                    swap(y1, y2);                int temp;                temp=getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1);                printf("%d\n",temp);            }            else if(cmd[0] == 'D')            {                scanf("%d%d%d",&x1,&y1,&n1);                ++x1;                ++y1;                if(a[x1][y1]<n1)                    n1 = a[x1][y1];                change(x1,y1, - n1);            }            else if(cmd[0] == 'M')            {                scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &n1);                ++x1;                ++x2;                ++y1;                ++y2;                if(a[x1][y1]<n1)                    n1 = a[x1][y1];                change(x1, y1, -n1);                change(x2, y2, n1);            }        }    }    return 0;}