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 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

很明显二维树状数组,算的时候就根据矩形面积来算。

二维和一维的主要区别在于 一维只枚举x,而二维枚举x,y。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #define N 1005
 5 using namespace std;
 6
 7 int map[N+1][N+1];
 8
 9
10 int lowbit(int x)
11 {
12     return x&(-x);
13 }
14
15 void update(int x,int y,int val)
16 {
17     int i, j;
18     for(i=x;i<=N;i+=lowbit(i))
19     for(j=y;j<=N;j+=lowbit(j))
20     map[i][j]+=val;
21 }
22
23
24 int query(int x,int y)
25 {
26     int sum=0;
27     for(int i=x;i>0;i-=lowbit(i))
28     for(int j=y;j>0;j-=lowbit(j))
29     sum+=map[i][j];
30     return sum;
31 }
32
33 int getnode(int x,int y)
34 {
35     return query(x,y)-query(x-1,y)-query(x,y-1)+query(x-1,y-1);
36 }
37
38 main()
39 {
40     int t, i, j, k=1, m;
41     char s[5];
42     int x1, y1, x2, y2, n1, n;
43     scanf("%d",&t);
44     while(t--)
45     {
46         printf("Case %d:\n",k++);
47         scanf("%d",&m);
48         memset(map,0,sizeof(map));
49
50         for(i=1;i<=N;i++)
51         {
52             for(j=1;j<=N;j++)
53                     update(i,j,1);
54
55         }
56
57         while(m--)
58         {
59             scanf("%s",s);
60
61             if(strcmp(s,"S")==0){
62                 scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
63
64                 if(x1>x2) swap(x1,x2);
65                 if(y1>y2) swap(y1,y2);
66
67                 int ans=query(x2+1,y2+1)-query(x1,y2+1)-query(x2+1,y1)+query(x1,y1);
68                 printf("%d\n",ans);
69             }
70             if(strcmp(s,"A")==0){
71                 scanf("%d %d %d",&x1,&y1,&n1);
72                 update(x1+1,y1+1,n1);
73             }
74             if(strcmp(s,"D")==0){
75                 scanf("%d %d %d",&x1,&y1,&n1);
76                 n=getnode(x1+1,y1+1);
77                 n=min(n,n1);
78                 update(x1+1,y1+1,-n);
79             }
80             if(strcmp(s,"M")==0){
81                 scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&n1);
82                 n=getnode(x1+1,y1+1);
83                 n=min(n,n1);
84                 update(x1+1,y1+1,-n);
85                 update(x2+1,y2+1,n);
86             }
87         }
88     }
89 }

HDU 1892 二维树状数组

时间: 2024-10-13 15:57:21

HDU 1892 二维树状数组的相关文章

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 1890 二维树状数组

#include<stdio.h> #include<string.h> #include<iostream> using namespace std; int sum[1010][1010]; int mark[1010][1010]; int add(int a,int b,int c) { int i,j; for(i=a;i<=1001;i+=(i&-i)) for(j=b;j<=1001;j+=(j&-j)) sum[i][j]+=

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 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;

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的子矩阵,使