hdu1892(二维树状数组)

2024-09-07 19:58
文章标签 数组 树状 二维 hdu1892

本文主要是介绍hdu1892(二维树状数组),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

See you~

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

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1892
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

解题思路:
二维树状数组的应用。注意下减法和移动的时候,如果要求减去或移动的书数小于n1,那么把现有书全部移走,当前位置为0。这里困惑了好久,详见程序注释部分,后来想到它为什么是错的,因为这是一个树状数组,树状数组存储的不是当前这个位置的数,而是某一连续区间的和,所以要想概率老师讲的那样,按面积来求该位置的值。
这题还有一个比较巧妙的地方,就是题目说初始时每个位置都是1。先把每个位置初始化成0,然后用二维树状数组进行加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;string str;const int maxn = 1003;
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 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 main()
{#ifdef DoubleQfreopen("in.txt","r",stdin);#endifint 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--){cin >> 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);cout << sum(x2 + 1 , y2 + 1) - sum(x1 , y2 + 1) - sum(x2 + 1 ,y1) + sum(x1 , y1) << endl;}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);/*if(maps[x1+1][y1+1] < n1)n1 = maps[x1+1][y1+1];*/int k = getsum(x1 , y1);n1 = min(n1 , k);add(x1 + 1 , y1 + 1 , -n1);}else if(str[0] == 'M'){scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n1);/*if(maps[x1+1][y1+1] < n1)n1 = maps[x1+1][y1+1];*/int k = getsum(x1 , y1);n1 = min(n1 , k);add(x1 + 1 , y1 + 1 , -n1);add(x2 + 1 , y2 + 1 , n1);}}}
}

 

这篇关于hdu1892(二维树状数组)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146011

相关文章

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

HDU 2159 二维完全背包

FATE 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

PHP7扩展开发之数组处理

前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: <?phpfunction array_concat ($arr, $prefix) {foreach($arr as $key => $val) {if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {$arr[