HDU 1892 二维树状数组

来源:互联网 发布:英雄382美工钢笔 编辑:程序博客网 时间:2024/05/16 10:06

四个操作:

1、S X1 Y1  X2 Y2 输出[x1 y1 x2 y2]矩阵的和。

2、A X1 Y1 N1 点[X1,Y1]的值加N1 。

3、D X1 Y1 N1 点[X1,Y1]的值减小N1,不足N1减为0。

4、M X1 Y1 X2 Y2 N1 将[X1,Y1]的值移动N1到[X2,Y2] ,不足则全部移动。


算法:二维树状数组


#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cmath>#include <cstring>#include <queue>#include <set>#include <vector>#include <stack>#include <map>#include <iomanip>#define PI acos(-1.0)#define Max 2005#define inf 2000000000#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)using namespace std;inline void RD(int &ret){    char c;    do    {        c = getchar();    }    while(c < '0' || c > '9');    ret = c - '0';    while((c=getchar()) >= '0' && c <= '9')        ret = ret * 10 + ( c - '0' );}int lowbit(int x ){    return x & (-x) ;}int n , m ;int a[1005][1005] ;void add(int x ,int y ,int num){    for (int i = x ;i <= n ;i += lowbit(i))    {        for (int j = y ; j <= m ;j += lowbit(j) )        {            a[i][j] += num ;        }    }}int sum(int x ,int y ){    int ans = 0 ;    for (int i = x ;i > 0 ;i -= lowbit(i))    {        for (int j = y ;j > 0 ; j -= lowbit(j))        ans += a[i][j] ;    }    return ans ;}int getsum(int x1, int y1, int x2 ,int y2){    return sum(x2,y2) + sum(x1 - 1,y1 - 1) - sum(x1 - 1,y2) - sum(x2,y1 - 1) ;}int getsum(int x1 ,int y1){    return sum(x1,y1) - sum(x1,y1 - 1) - sum(x1 - 1 ,y1) + sum(x1 - 1 , y1 - 1 ) ;}int main(){#ifndef ONLINE_JUDGE    freopen("acm.txt", "r", stdin);#endif    int T ;    RD(T) ;    int cc = 0 ;    while(T -- )    {        int cas ;        RD(cas) ;        n = 1004 , m = 1004  ;        mem(a,0) ;        printf("Case %d:\n",++cc) ;        REP(i,1,n)REP(j,1,m){            add(i,j,1) ;        }        while(cas -- )        {            char op ;            op = getchar() ;            if(op == 'S')            {                int x1 ,y1, x2 ,y2 ;                RD(x1) ; RD(y1) ;RD(x2) ;RD(y2) ;                x1 ++ ,y1 ++ ,x2 ++ ,y2 ++ ;//因为X1,X2,Y1,Y2是从0开始的。                if(x1 > x2)swap(x1,x2) ;//注意X2,Y2不一定比X1,Y1大,这是个坑。                if(y1 > y2)swap(y1,y2) ;                printf("%d\n",getsum(x1,y1,x2,y2)) ;            }            else if(op == 'A')            {                int x1 ,y1 ,num ;                RD(x1) ;RD(y1) ;RD(num) ;                x1 ++ ,y1 ++ ;                add(x1,y1,num) ;            }            else if(op == 'D')            {                int x1 ,y1 ,num ;                RD(x1) ;RD(y1) ;RD(num) ;                x1 ++ ,y1 ++ ;                int num1 = getsum(x1,y1) ;                if(num1 >= num)                add(x1,y1,-num) ;                else                add(x1,y1,-num1) ;            }            else if(op == 'M')            {                int x1 ,y1 ,x2, y2 ,num ;                RD(x1) ; RD(y1) ;RD(x2) ;RD(y2) ;RD(num) ;                x1 ++ ,y1 ++ ,x2 ++ ,y2 ++ ;                int num1 = getsum(x1,y1) ;                if(num1 >= num )                {                    add(x1,y1,-num ) ;                    add(x2,y2,num) ;                }                else                {                    add(x1,y1,-num1) ;                    add(x2,y2,num1) ;                }            }        }    }    return 0;}


原创粉丝点击