【原】 POJ 2155 Matrix 2D树状数组 解题报告

 

http://poj.org/problem?id=2155

 

题目要求修改一个区域,然后求一个元素的值。貌似和树状数组的功能完全相反。但这题,应该
说这个思路的精妙之处就体现在这里。我认为关键是要理解“树状”的概念。画一个一维的树状数
组图形,就会发现所有的元素都会链接到2,4,8,16,32……这条“主干”上来。那么,修改了“主干”,
其实就相当于修改了整个“树”。

对于每个元素a,“主干”可以分为两个部分,
Up(a) = { a1 = a, a2 = a1+ lowbit(a1), a3 = a2 + lowbit(a2), ... }
Down(a) = { a1 =a, a2 = a1 -lowbit(a1), a3 = a2 - lowbit(a2), ... }。
当然这里不是完全的对应主干上的每个元素。对于任意a<b,up(a)与down(b)的交集都只有一个元素。
若要对[a,b]内的元素进行+n操作,只要down(a-1)的元素-n, down(b)的元素+n就好了。

设a<=c<=b,查询c时则对up(c)进行求和。因为up(c)与down(b)只有一个共同元素,所以可以完整的
体现修改。以上是一维的情况。可以非常直接的推论到二维。只要对x, y坐标同时up或down。理解了
上面的思路,这题就迎刃而解了。

 

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 <= i, j <= N). 
We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions. 
1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2). 
2. Q x y (1 <= x, y <= n) querys A[x, y].

Input

The first line of the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case. 
The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above.

Output

For each querying output one line, which has an integer representing A[x, y]. 
There is a blank line between every two continuous test cases.

Sample Input

1

2 10

C 2 1 2 2

Q 2 2

C 2 1 2 1

Q 1 1

C 1 1 2 1

C 1 2 1 2

C 1 1 2 2

Q 1 1

C 1 1 2 1

Q 2 1

Sample Output

1

0

0

1

 

   1: const int N = 1001 ;
   2:  
   3: int tree[N][N] = {0} ;
   4:  
   5: //此过程是向上求的,不同于标准向下求
   6: int GetSum( int n, int x, int y )
   7: {
   8:     int y1 ;
   9:     int sum = 0 ;
  10:     while( x<=n ) //***
  11:     {
  12:         y1 = y ;
  13:         while( y1<=n )
  14:         {
  15:             sum += tree[x][y1] ;
  16:             y1 += ( y1 & -y1 ) ;  //***
  17:         }
  18:         x += ( x & -x ) ;
  19:     }
  20:     return sum ;
  21: }
  22:  
  23: //此过程是向下求的,不同于标准向上求
  24: void AddVal( int x, int y, int val )
  25: {
  26:     int y1 ;
  27:     while( x>0 )  //***
  28:     {
  29:         y1 = y ;
  30:         while( y1>0 )
  31:         {
  32:             tree[x][y1] += val ;
  33:             y1 -= ( y1 & -y1 ) ;  //***
  34:         }
  35:         x -= ( x & -x ) ;
  36:     }
  37: }
  38:  
  39: void run2155()
  40: {
  41:     int caseNum,n,t ;
  42:     char c ;
  43:     int x1,y1,x2,y2 ;
  44:     int i ;
  45:  
  46:     scanf( "%d" , &caseNum ) ;
  47:     while( caseNum-- )
  48:     {
  49:         scanf( "%d%d", &n,&t ) ;
  50:  
  51:         memset(tree,0,sizeof(tree)) ; //对数组赋值
  52:  
  53:         while( t-- )
  54:         {
  55:             scanf( "\n%c", &c ) ;
  56:             if( c=='C' )
  57:             {
  58:                 scanf( "%d%d%d%d", &x1,&y1,&x2,&y2 ) ;
  59:                 AddVal( x2, y2, 1 ) ;
  60:                 AddVal( x1-1, y2, -1 ) ;
  61:                 AddVal( x2, y1-1, -1 ) ;
  62:                 AddVal( x1-1, y1-1, 1 ) ;
  63:             }
  64:             else
  65:             {
  66:                 scanf( "%d%d", &x1,&y1 ) ;
  67:                 printf( "%d\n", GetSum(n,x1,y1)%2 ) ;
  68:             }
  69:         }
  70:         printf("\n") ;
  71:     }
  72: }

转载于:https://www.cnblogs.com/allensun/archive/2010/11/05/1870107.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值