zoukankan      html  css  js  c++  java
  • hihocoder-Week 172--Matrix Sum

    hihocoder-Week 172--Matrix Sum

     Matrix Sum

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    You are given an N × N matrix. At the beginning every element is 0. Write a program supporting 2 operations:

     1. Add x y value: Add value to the element Axy. (Subscripts starts from 0

    2. Sum x1 y1 x2 y1: Return the sum of every element Axy for x1 ≤ x ≤ x2y1 ≤ y ≤ y2.

    输入

    The first line contains 2 integers N and M, the size of the matrix and the number of operations.

    Each of the following M line contains an operation.

    1 ≤ N ≤ 1000, 1 ≤ M ≤ 100000

    For each Add operation: 0 ≤ x < N, 0 ≤ y < N, -1000000 ≤ value ≤ 1000000

    For each Sum operation: 0 ≤ x1 ≤ x2 < N, 0 ≤ y1 ≤ y2 < N 

    输出

    For each Sum operation output a non-negative number denoting the sum modulo 109+7.

    样例输入
    5 8
    Add 0 0 1
    Sum 0 0 1 1
    Add 1 1 1
    Sum 0 0 1 1
    Add 2 2 1
    Add 3 3 1
    Add 4 4 -1
    Sum 0 0 4 4 
    样例输出
    1
    2
    3 

    题解:

      二维树状数组

    假设我们有二维数组A[1..N][1..N],二维树状数组可以支持对A[][]进行如下操作: 
    1. add(x, y, val): A[x][y] += val 
    2. sum(x, y): 求和sum(A[1..x][1..y])

    和一维情况类似,能支持以上两个操作实际就能支持任意修改A[x][y]的值以及求一个子矩阵A[a..b][c..d]的和。

    二维树状数组以上两个操作的复杂度都是O(logNlogN)的。

    二维树状数组BIT2[x][y]与A[][]的对应关系如下图:

    直观理解就是x坐标和y坐标分别是一个一维树状数组,假设一维情况中BIT[x]对应的是A[i1], A[i2] ... A[ik], BIT[y]对应的是A[j1], A[j2], ... A[jt]。那么BIT2[x][y] 相当于笛卡尔积 {i1, i2, ... ik} x {j1, j2, ... jt}:

    BIT2][x][y] = ΣA[i][j] | {i in {i1 ... ik}且 j in {j1 ... jt}}

    #include <cstdio>  
    #include <cstdlib> 
    #include <cstring> 
    
    const int MAXN = 1000 + 10; 
    const int MOD = 1e9 + 7; 
    
    int n, m, mp[MAXN][MAXN]; 
    
    inline int lowbit(int x){
    	return ( x & (-x)); 
    }
    
    void Add(int x, int y, int val){
    	for(int i=x; i <= n; i += lowbit(i) ){
    		for(int j=y; j <= n; j += lowbit(j) ){
    			mp[i][j] += val; 
    			mp[i][j] %= MOD; 
    		}
    	}
    }
    
    long long GetSum(int x1, int y1, int x2, int y2){
    	long long ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0; 
    	for(int i=x2; i>0; i-=lowbit(i)){
    		for(int j=y2; j>0; j-=lowbit(j)){
    			ans1 += mp[i][j]; 
    			ans1 %= MOD;  
    		}
    	}
    	for(int i=x1; i>0; i-=lowbit(i)){
    		for(int j=y1; j>0; j-=lowbit(j)){
    			ans2 += mp[i][j]; 
    			ans2 %= MOD; 
    		} 
    	} 
    
    	for(int i=x1; i>0; i-=lowbit(i)){
    		for(int j=y2; j>0; j-=lowbit(j)){
    			ans3 += mp[i][j]; 
    			ans3 %= MOD; 
    		}
    	}
    	for(int i=x2; i>0; i-=lowbit(i)){
    		for(int j=y1; j>0; j-=lowbit(j)){
    			ans4 += mp[i][j]; 
    			ans4 %= MOD; 
    		}
    	} 
    	return (ans1 + ans2 - ans3 - ans4 + MOD) % MOD; 
    }
    
    int main(){
    	freopen("in.txt", "r", stdin); 
    
    	int x1, x2, y1, y2, val; 
    	long long ans; 
    	char ch[10]; 
    
    	while(scanf("%d %d", &n, &m) != EOF){  
    		memset(mp, 0,  sizeof(mp)); 
    
    		for(int i=0; i<m; ++i){
    			getchar(); 
    			scanf("%s", ch); 
    
    			if(strcmp(ch, "Add") == 0){ 
    				scanf("%d %d %d", &x1, &y1, &val);  
    				Add(x1 + 1, y1 + 1, val);  
    
    			}else if(strcmp(ch, "Sum") == 0){ 
    				scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 
    				ans = GetSum(x1, y1, x2 + 1, y2 + 1); 
    
    				printf("%lld
    ", ans ); 
    			} 
    		} 
    	} 
    	return 0; 
    }
    

      

  • 相关阅读:
    1-29反射
    1-28Map简介
    1-27TreeSet简介
    1-26HashSet简介
    1-25泛型
    1-24List三个子类的特点
    1-23集合概述
    Java接口
    1-22日期类型
    简易计算器的实现
  • 原文地址:https://www.cnblogs.com/zhang-yd/p/7672706.html
Copyright © 2011-2022 走看看