HDU 2642 二维树状数组问题

简单:Stars

http://acm.hdu.edu.cn/showproblem.php?pid=2642

题目大概意思: 在某个位置可以是 B (明亮的星星) 或者是 D (昏暗的星星) 当 Q x1 x2 y1 y2 时候 求 在 x1 y1 到 x2 y2 中一共有多上个星星。


思路:用二维树状数组进行模拟 其算法的效率为 log(n) java 代码如下:

import java.util.Scanner;
/*
 * 此题用 二维线段树求解
 */
public class HDU2642 {
	int c[][];
	static final int n = 1001;
	boolean vis[][];
	public HDU2642(){
		c = new int[n][n]; vis = new boolean[n][n];
	}
	private int lowbit(int n){
		return n&(-n);
	}
	// 修改 给 x1 , x2 位置 增加  data 后的修改
	public void modify(int x, int y, int data){
		for(int i =x ; i<=n; i += lowbit(i)){
			for(int j=y; j<=n; j+= lowbit(j)){
				c[i][j] += data;
			}
		}
	}
	// 得到从 (0,0) 到 (x,y) 矩阵的 和
	public int sum(int x,int y){
		int result = 0;
		for(int i=x; i>0; i -= lowbit(i)){
			for(int j=y; j>0; j -= lowbit(j)){
				result += c[i][j];
			}
		}
		return result;
	}
	// 得到 (x1,y1) 到 (x2, y2) 的 子矩阵的和
	public int getSubMaxtrix(int x1, int y1, int x2, int y2){
		// 让 x2>x1 y2>y1;
		if( x2 < x1){int temp = x1; x1 = x2; x2 = temp;};
		if( y2 < y1){int temp = y1; y1 = y2; y2 = temp;};
		return sum(x2,y2) - sum(x1-1,y2) - sum(x2,y1-1) + sum(x1-1,y1-1);
	}
	public void solve(){
		int m ;
		Scanner sc = new Scanner(System.in);
		m = sc.nextInt();
		for(int i=0; i<m; i++){
			String executeChar ; int x, y;
			executeChar = sc.next();
			if(executeChar.equals("B")){// 如果是 Bright 
				x = sc.nextInt(); y = sc.nextInt();
				x++; y++;
				if( !vis[x][y]){
					vis[x][y] = true; modify(x, y, 1);
				}
			}
			else if(executeChar.equals("D")){
				x = sc.nextInt(); y = sc.nextInt();
				x++; y++;
				if(vis[x][y]){
					vis[x][y] = false; modify(x,y,-1);
				}
			}
			else if(executeChar.equals("Q")){
				int x1,x2,y1,y2;
				x1 = sc.nextInt(); x2 = sc.nextInt(); y1 = sc.nextInt(); y2 = sc.nextInt();
				x1++; y1++; x2++; y2++;
				System.out.println(getSubMaxtrix(x1, y1, x2, y2));
			}
		}
	}
	public static void main(String[] args) {
		new HDU2642().solve();
	}
}

树状数组的知识点:

定义 如下: 有数组 a[1........n] 有 c[] 有 c[n] = a[ n - 2^k+1] + ...............a[n]; k 为 n 化为 2进制后 0  的个数。是在网上学的 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值