HDU 1892 See you~(二维树状数组)

See you~

Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 4753    Accepted Submission(s): 1518

Problem Description

Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algorithm and Programming, and I met so many good friends. I want to say sorry to Mr, Yin, I must leave now ~~>.<~~. I am very sorry, we could not advanced to the World Finals last year.
When coming into our training room, a lot of books are in my eyes. And every time the books are moving from one place to another one. Now give you the position of the books at the early of the day. And the moving information of the books the day, your work is to tell me how many books are stayed in some rectangles.
To make the problem easier, we divide the room into different grids and a book can only stayed in one grid. The length and the width of the room are less than 1000. I can move one book from one position to another position, take away one book from a position or bring in one book and put it on one position.

Input

In the first line of the input file there is an Integer T(1<=T<=10), which means the number of test cases in the input file. Then N test cases are followed.
For each test case, in the first line there is an Integer Q(1<Q<=100,000), means the queries of the case. Then followed by Q queries.
There are 4 kind of queries, sum, add, delete and move.
For example:
S x1 y1 x2 y2 means you should tell me the total books of the rectangle used (x1,y1)-(x2,y2) as the diagonal, including the two points.
A x1 y1 n1 means I put n1 books on the position (x1,y1)
D x1 y1 n1 means I move away n1 books on the position (x1,y1), if less than n1 books at that position, move away all of them.
M x1 y1 x2 y2 n1 means you move n1 books from (x1,y1) to (x2,y2), if less than n1 books at that position, move away all of them.
Make sure that at first, there is one book on every grid and 0<=x1,y1,x2,y2<=1000,1<=n1<=100.

Output

At the beginning of each case, output "Case X:" where X is the index of the test case, then followed by the "S" queries.
For each "S" query, just print out the total number of books in that area.

Sample Input

2
3
S 1 1 1 1
A 1 1 2
S 1 1 1 1
3
S 1 1 1 1
A 1 1 2
S 1 1 1 2

Sample Output

Case 1:
1
3
Case 2:
1
4

Author

Sempr|CrazyBird|hust07p43

Source

HDU 2008-4 Programming Contest

Recommend

lcy   |   We have carefully selected several similar problems for you:  1541 2492 1894 1394 3450

/*
给定4种操作: 
S x1 y1 x2 y2 询问以(x1 , y1) - (x2 , y2)为对角线的矩形的面积,但是这个对角线不一定是正对角线。
A x1 y1 n 把点(x1 , y1)加上n。
D x1 y1 n点(x1 , y1)减去n如果不足n就全部删除即可。
M x1 y1 x2 y2 n 把点(x1 , y1)点值中扣除n加到(x2 , y2),如果不过n则把(x1 , y1)值全部加到(x2 , y2)
*/
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
#define lowbit(x) x&(-x)
#define N 1005
using namespace std;
int t,n;
int c[N][N];
void update(int x,int y,int val)
{
    //int flag=fabs(val);
    // while(x<N)
    // {
        // while(y<N)
        // {
            // cout<<x<<" "<<y<<endl;
            // c[x][y]+=val;
            // if(c[x][y]<0)
            // {
                // flag=c[x][y]+val;
                // c[x][y]=0;
            // }
            // y+=lowbit(y);
        // }
        // x+=lowbit(x);
    // }
    for(int i=x;i<N;i+=lowbit(i))
    {
        for(int j=y;j<N;j+=lowbit(j))
        {
            c[i][j]+=val;
            // if(c[i][j]<0)
            // {
                // flag=c[i][j]+val;
                // c[i][j]=0;
            // }
        }
    }
    // return val;//返回你实际搬运的东西
}
int getsum(int x,int y)
{
    int s=0;
    // while(x>0)
    // {
        // while(y>0)
        // {
            // s+=c[x][y];
            // y-=lowbit(y);
        // }
        // x-=lowbit(x);
    // }
    for(int i=x;i>0;i-=lowbit(i))
    {
        for(int j=y;j>0;j-=lowbit(j))
        {
            s+=c[i][j];
        }
    }
    return s;
}
// int getS(int x1,int y1,int x2,int y2)
// {
    // cout<<getsum(x1,y1)<<" "<<getsum(x1-1,y2)<<" "<<getsum(x2,y1-1)<<" "<<getsum(x2-1,y2-1)<<endl;
    // return getsum(x1,y1)-getsum(x1,y2-1)-getsum(x2-1,y1)+getsum(x2-1,y2-1);
// }
int main()
{
    //freopen("C:\\Users\\acer\\Desktop\\in.txt","r",stdin);
    scanf("%d",&t);
    int Case=1;
    while(t--)
    {
        printf("Case %d:\n",Case++);
        scanf("%d",&n);
        int x1,x2,y1,y2,val;
        memset(c,0,sizeof c);
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                update(i,j,1);
        //cout<<getsum(1,1)<<" "<<getsum(2,2)<<endl;
        for(int i=0;i<n;i++)
        {
            //getchar();
            char op[5];
            scanf("%s",&op);
            //getchar();
            if(op[0]==‘A‘||op[0]==‘D‘)
            {
                scanf("%d%d%d",&x1,&y1,&val);
                x1++;y1++;
                if(op[0]==‘D‘)
                    val=-min(val,getsum(x1,y1)-getsum(x1-1,y1)-getsum(x1,y1-1)+getsum(x1-1,y1-1));
                update(x1,y1,val);
            }
            else if(op[0]==‘M‘)
            {
                scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);
                x1++;x2++;y1++;y2++;
                int temp=min(val,getsum(x1,y1)-getsum(x1-1,y1)-getsum(x1,y1-1)+getsum(x1-1,y1-1));//这个是你实际从前一个点搬走的东西
                update(x1,y1,-temp);
                update(x2,y2,temp);
            }
            else
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                if(x1<x2)
                    swap(x1,x2);
                if(y1<y2)
                    swap(y1,y2);//并不一定是正对角线
                x1++;x2++;y1++;y2++;
                //cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
                //cout<<"getsum(x2,y2)="<<getsum(x2,y2)<<endl;
                // cout<<getsum(x1,y1)<<" "<<getsum(x1,y2-1)<<" "<<getsum(x2-1,y1)<<" "<<getsum(x2-1,y2-1)<<endl;
                printf("%d\n",getsum(x1,y1)-getsum(x1,y2-1)-getsum(x2-1,y1)+getsum(x2-1,y2-1));
            }
        }
    }
    return 0;
}
/*
Case 1:
1
3
Case 2:
1
4
*/
时间: 2024-11-03 03:34:40

HDU 1892 See you~(二维树状数组)的相关文章

HDU 1892 See you~ (二维树状数组)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1892 See you~ Problem Description Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algorithm and Programming, and I met so many good friends. I want to say so

hdu 5517 Triple(二维树状数组)

HDU 5517 题目:给出一种有三个元素的顺序,这个数据定义一种偏序,当且仅当一个三元数的所有元素都大于等于另一个时这个数比另一个大.求这个一个集合中不比任何数小的三元数有多少个. 思路:首先排序去重,此时第一维有序,不用考虑,然后只有不存在比当前数的另外两维都大的数时当前数是可选的,用二位树装数组维护这个信息即可. /* * @author: Cwind */ #include <bits/stdc++.h> using namespace std; #define IOS std::io

HDU 1892 二维树状数组

See you~ Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3485    Accepted Submission(s): 1103 Problem Description Now I am leaving hust acm. In the past two and half years, I learned so many kno

HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle Accepts: 42 Submissions: 269 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一

hdu 5517 Triple(二维树状数组)

题目链接:hdu 5517 Triple 题意: 有n个两元组A,有m个三元组B,然后set C有一个计算方式. 现在让你找set TOP的size. 题解: 理解题意后,显然对于每个b的分组,只有最大的a才有贡献, 然后就可以发现set B中每个元素按照e分组后,只会对应一个a,所以最多有1e5个三元组可能有贡献. 然后将这个三元组排一下序,用二维树状数组搞搞就行了. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i&l

hdu 4456 Crowd(二维树状数组)

题目链接:hdu 4456 Crowd 题目大意:给定N,然后M次操作 1 x y z:在x,y的位置加z 2 x y z:询问与x,y曼哈顿距离小于z的点值和. 解题思路:将矩阵旋转45度,然后询问就等于是询问一个矩形,可以用容斥定理搞,维护用二维树状数组,但是空间开 不下,直接用离散化,将有用到的点处理出来. #include <cstdio> #include <cstring> #include <algorithm> using namespace std;

hdoj 1892(二维树状数组)

Problem H Time Limit : 5000/3000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 8   Accepted Submission(s) : 3 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Now I am leaving hust acm. In

HDU_4456_二维树状数组

http://acm.hdu.edu.cn/showproblem.php?pid=4456 第一道二维树状数组就这么麻烦,题目要计算的是一个菱形范围内的和,于是可以把原来的坐标系旋转45度,就是求一个正方形范围内的和,这里还涉及到坐标系平移和放大,由于题目数据较大,用了离散化来保存需要处理的点,放在h数组内,对应的二维树状数组存在tree数组内. #include<iostream> #include<cstring> #include<cstdio> #includ

hdu6078 Wavel Sequence dp+二维树状数组

//#pragma comment(linker, "/STACK:102400000,102400000") /** 题目:hdu6078 Wavel Sequence 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078 题意:给定a序列和b序列.从a中取一个子序列x(数的位置顺序保持不变),子序列每个数满足a1<a2>a3<a4>a5<a6... 波浪形 从b中取相同长度的子序列y,也满足波浪形. 如果x

HDU1559 最大子矩阵 (二维树状数组)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1559 最大子矩阵 Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2901    Accepted Submission(s): 1454 Problem Description 给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使