HLJUOJ1118(二维树状数组)

来源:互联网 发布:ubuntu如何下载qq 编辑:程序博客网 时间:2024/05/16 04:29

1118: Matrix

Time Limit: 4 Sec  Memory Limit: 128 MB
Submit: 77  Solved: 12
[Submit][Status][Web Board]

Description

给定一个1000*1000的二维矩阵,初始矩阵中每个数都为1,然后为矩阵有4种操作.

S x1 y1 x2 y2:计算(x1,y1)、(x2,y2)围成的矩阵内所有元素的和。

A x y v:将(x,y)增加v

D x y v:将(x,y)减少v

M x1 y1 x2 y2 v:将(x1,y1)元素中的v转移到(x2,y2)中去。

所有操作数都为正数。

若某一操作将矩阵中元素降到1以下,一律按1处理。

x,y从0开始编号。

Input

 第一行一个数t,代表样例个数:

每组样例第一行一个数m,代表m次操作,m<100000

接下来m行代表m次操作

Output

 每组样例输出一个

Case i:

i代表第i个样例

 对于每一个操作S,输出一行,代表计算结果。

所有结果均不会超过int范围

Sample Input

14A 1 1 1M 1 1 2 2 1D 2 2 1S 1 1 2 2

Sample Output

Case 1:4



解题思路:
和昨晚做的HDU上的一道二维树状数组差不多,应该都属于模板题,不过两道题上细节处理不同。这道题要求做减法和移动的时候如果移动的n1大于该位置原有的k,那么只移动k-1,即保证该位置至少为1.



完整代码:
#include <functional>#include <algorithm>#include <iostream>#include <fstream>#include <sstream>#include <iomanip>#include <numeric>#include <cstring>#include <climits>#include <cassert>#include <complex>#include <cstdio>#include <string>#include <vector>#include <bitset>#include <queue>#include <stack>#include <cmath>#include <ctime>#include <list>#include <set>#include <map>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")typedef long long LL;typedef double DB;typedef unsigned uint;typedef unsigned long long uLL;/** Constant List .. **/ //{const int MOD = int(1e9)+7;const int INF = 0x3f3f3f3f;const LL INFF = 0x3f3f3f3f3f3f3f3fLL;const DB EPS = 1e-9;const DB OO = 1e20;const DB PI = acos(-1.0); //M_PI;char str[3];const int maxn = 1111;int maps[maxn][maxn];int lowbit(int x){    return x & (-x);}void add(int x , int y , int d){    for(int i = x ; i < maxn ; i += lowbit(i))    {        for(int j = y ; j < maxn ; j += lowbit(j))        {            maps[i][j] += d;        }    }}void inline init(){    memset(maps , 0 , sizeof(maps));    for(int i = 1 ; i < maxn; i ++)    {        for(int j = 1 ; j < maxn ; j ++)        {            add(i , j , 1);        }    }}int sum(int x , int y){    int res = 0;    for(int i = x ; i > 0 ; i -= lowbit(i))    {        for(int j = y ; j > 0 ; j -= lowbit(j))        {            res += maps[i][j];        }    }    return res;}int getsum(int x , int y){    return sum(x + 1 , y + 1) - sum(x , y + 1) - sum(x + 1 , y) + sum(x , y);}int min(int a , int b){    return a < b ? a : b;}int main(){    #ifdef DoubleQ    freopen("in.txt","r",stdin);    #endif    int T;    scanf("%d",&T);    int x1 , y1 , x2 , y2 , n1;    int cas = 1;    while(T--)    {        printf("Case %d:\n",cas++);        init();        int q;        scanf("%d",&q);        while(q--)        {            scanf("%s",str);            if(str[0] == 'S')            {                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);                if(x1 > x2)                    swap(x1 , x2);                if(y1 > y2)                    swap(y1 , y2);                int res =  sum(x2 + 1 , y2 + 1) - sum(x1 , y2 + 1) - sum(x2 + 1 ,y1) + sum(x1 , y1) ;                printf("%d\n",res);            }            else if(str[0] == 'A')            {                scanf("%d%d%d",&x1,&y1,&n1);                add(x1 + 1 , y1 + 1 , n1);            }            else if(str[0] == 'D')            {                scanf("%d%d%d",&x1,&y1,&n1);                int k = getsum(x1 , y1);                //n1 = min(n1 , k);                if(n1 >=  k)                    n1 = k - 1;                add(x1 + 1 , y1 + 1 , -n1);            }            else if(str[0] == 'M')            {                scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n1);                int k = getsum(x1 , y1);                //n1 = min(n1 , k);                if(n1 >= k)                    n1 = k - 1;                add(x1 + 1 , y1 + 1 , -n1);                add(x2 + 1 , y2 + 1 , n1);            }        }    }}


0 0