TOJ 2725 See you~(二维树状数组单点更新区间查询)

描述

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.

输入

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.

输出

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.

样例输入

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

样例输出

Case 1:
1
3
Case 2:
1
4

题意

1000*1000的矩阵上每个格点放了1本书

Q个操作

1.查询[X1,Y1]-[X2,Y2]总共放了几本书

2.在[X1,Y1]增加n1本书

3.在[X1,Y1]移除n1本书,若不够则全移走

4.把[X1,Y1]上的n1本书移到[X2,Y2]上,若不够则全移到[X2,Y2]

题解

二维树状数组单点修改,区间查询

1.区间查询分成4块,([1,1]-[X1,Y1])+([1,1]-[X2,X2])-([1,1]-[X2+1,Y1])-([1,1]-[X1,Y2+1])

2.直接单点更新

3.区间查询单点,这里X2=X1,Y2=Y1,查出来的与n1比个小即为需要移走的数

4.同三

这里操作1,并没有严格[X1,Y1]<[X2,Y2],所以需要交换

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 const int N=1234;
 5 const int n=1005;
 6
 7 struct BIT2{
 8     int sum[N][N];
 9     void init()
10     {
11         memset(sum,0,sizeof sum);
12         for(int i=0;i<=n;i++)
13             for(int j=0;j<=n;j++)
14                 update(i,j,1);
15     }
16     int lowbit(int x){return x&(-x);}
17     int update(int x,int y,int w)
18     {
19         x++,y++;
20         for(int i=x;i<=n;i+=lowbit(i))
21             for(int j=y;j<=n;j+=lowbit(j))
22                 sum[i][j]+=w;
23     }
24     int query(int x,int y)
25     {
26         x++,y++;
27         int ans=0;
28         for(int i=x;i>0;i-=lowbit(i))
29             for(int j=y;j>0;j-=lowbit(j))
30                 ans+=sum[i][j];
31         return ans;
32     }
33 }T;
34 int main()
35 {
36     int t,q,x1,y1,x2,y2,n1,o=1;
37     char op[3];
38     scanf("%d",&t);
39     while(t--)
40     {
41         printf("Case %d:\n",o++);
42         T.init();
43         scanf("%d",&q);
44         for(int i=0;i<q;i++)
45         {
46             scanf("%s",op);
47             if(op[0]==‘S‘)
48             {
49                 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
50                 if(x1>x2)swap(x1,x2);
51                 if(y1>y2)swap(y1,y2);
52                 int ans=T.query(x2,y2)+T.query(x1-1,y1-1)-T.query(x2,y1-1)-T.query(x1-1,y2);
53                 printf("%d\n",ans);
54             }
55             if(op[0]==‘A‘)
56             {
57                 scanf("%d%d%d",&x1,&y1,&n1);
58                 T.update(x1,y1,n1);
59             }
60             if(op[0]==‘D‘)
61             {
62                 scanf("%d%d%d",&x1,&y1,&n1);
63                 int ans=T.query(x1,y1)+T.query(x1-1,y1-1)-T.query(x1,y1-1)-T.query(x1-1,y1);
64                 T.update(x1,y1,-min(n1,ans));
65             }
66             if(op[0]==‘M‘)
67             {
68                 scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n1);
69                 int ans=T.query(x1,y1)+T.query(x1-1,y1-1)-T.query(x1,y1-1)-T.query(x1-1,y1);
70                 T.update(x1,y1,-min(n1,ans));
71                 T.update(x2,y2,min(n1,ans));
72             }
73         }
74     }
75     return 0;
76 }

原文地址:https://www.cnblogs.com/taozi1115402474/p/9496025.html

时间: 2024-11-03 20:54:22

TOJ 2725 See you~(二维树状数组单点更新区间查询)的相关文章

【2018年全国多校算法寒假训练营练习比赛(第五场)-E】情人节的电灯泡(二维树状数组单点更新+区间查询)

试题链接:https://www.nowcoder.com/acm/contest/77/E 题目描述 情人节到了,小芳和小明手牵手,打算过一个完美的情人节,但是小刚偏偏也来了,当了一个明晃晃的电灯泡,小明很尴尬,就和小刚说,我交给你个任务,你完成了我俩就带你玩,否则你就回家吧.小刚很有当单身狗的觉悟,他坚决不想让小明过好情人节,同为单身狗的你能帮帮他吗?现在有一个n×n(1 <= n <= 1000)的格子,每一个格子都有一个电灯泡,可能是亮的,也可能是灭的(1代表亮, 0代表灭),现在有两

POJ 1195-Mobile phones(二维树状数组-区间更新区间查询)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 17661   Accepted: 8173 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The

一维 + 二维树状数组 + 单点更新 + 区间更新 详解

树状数组详解: 假设一维数组为A[i](i=1,2,...n),则与它对应的树状数组C[i](i=1,2,...n)是这样定义的: C1 = A1 C2 = A1 + A2 C3 = A3 C4 = A1 + A2 + A3 + A4 C5 = A5 C6 = A5 + A6 ................. C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 ................ 如图可知: 为奇数的时候他是代表他本身,而为偶数的时候则是代表着自

【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询

题目描述 JYY有N个平面坐标系中的矩形.每一个矩形的底边都平行于X轴,侧边平行于Y轴.第i个矩形的左下角坐标为(Xi,Yi),底边长为Ai,侧边长为Bi.现在JYY打算从这N个矩形中,随机选出两个不同的矩形,并计算它们的并的大小.JYY想知道,交的大小的期望是多少.换句话说即求在所有可能的选择中,两个矩形交的面积的平均大小是多大. 输入 输入一行包含一个正整数N. 接下来N行,每行4个整数,分别为Xi,Yi,Ai,Bi 2 < =  N < =  2*10^5, 0 < =  Xi,

【poj1195】Mobile phones(二维树状数组)

题目链接:http://poj.org/problem?id=1195 [题意] 给出一个全0的矩阵,然后一些操作 0 S:初始化矩阵,维数是S*S,值全为0,这个操作只有最开始出现一次 1 X Y A:对于矩阵的X,Y坐标增加A 2 L B R T:询问(L,B)到(R,T)区间内值的总和 3:结束对这个矩阵的操作 [思路] 二维树状数组单点更新+区域查询,可作为模板题. 注意坐标是从0开始,所以要+1 [代码] 1 #include<cstdio> 2 #include<cstrin

POJ 1195 Mobile phones(二维树状数组)

题目链接:POJ 1195 题意: 给出一个S*S的矩阵(行.列号从1开始),每个元素初始值为0,有两种操作:一种是第X行第Y列元素值加A:另一种是查询给定范围矩阵的所有元素之和(L<=X<=R,B<=Y<=T). 分析: 查询给定范围矩阵的所有元素之和是二维区间和,可以转换为二维前缀和求值.类比一维前缀和求法,二维区间和S(L, B, R, T) = S(1, 1, R, T) - S(1 ,1, L-1, T) - S(1, 1, R, B-1) + S(1, 1, L-1,

学习笔记——二维树状数组

不知道为什么,就是想把这个坑给填了... 二维树状数组,本质上还是树状数组,只是在一维的基础上变成了二维... 单点修改  1到i,j查询和一维基本一样,直接上代码 #include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #define N 3010 using namespace std; int a[N][N],n; inline int lowbit(int x

【二维树状数组】See you~

https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A x y n1 :给格点(x,y)的值加n1 D x y n1: 给格点(x,y)的值减n1,如果现在格点的值不够n1,把格点置0 M x1 y1 x2 y2:(x1,y1)移动给(x2,y2)n1个 S x1 y1 x2 y2 查询子矩阵的和 [思路] 当然是二维树状数组 但是一定要注意:lowbi

POJ 2155 Matrix(二维树状数组,绝对具体)

Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20599   Accepted: 7673 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1