题目
地图上有 N N N 个目标,用整数 X i , Y i X_i,Y_i Xi,Yi 表示目标在地图上的位置,每个目标都有一个价值 W i W_i Wi。
注意:不同目标可能在同一位置。
现在有一种新型的激光炸弹,可以摧毁一个包含 R × R R×R R×R 个位置的正方形内的所有目标。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个正方形的边必须和 x , y x,y x,y 轴平行。
若目标位于爆破正方形的边上,该目标不会被摧毁。
求一颗炸弹最多能炸掉地图上总价值为多少的目标。
输入格式
第一行输入正整数 N N N 和 R R R,分别代表地图上的目标数目和正方形的边长,数据用空格隔开。
接下来 N N N 行,每行输入一组数据,每组数据包括三个整数 X i , Y i , W i X_i,Y_i,W_i Xi,Yi,Wi,分别代表目标的 x x x 坐标, y y y 坐标和价值,数据用空格隔开。
输出格式
输出一个正整数,代表一颗炸弹最多能炸掉地图上目标的总价值数目。
数据范围
- 0 ≤ R ≤ 1 0 9 0≤R≤10^9 0≤R≤109
- 0 < N ≤ 10000 0<N≤10000 0<N≤10000
- 0 ≤ X i , Y i ≤ 5000 0≤X_i,Y_i≤5000 0≤Xi,Yi≤5000
- 0 ≤ W i ≤ 1000 0≤W_i≤1000 0≤Wi≤1000
输入样例
2 1
0 0 1
1 1 1
输出样例
1
分析
因为 X i , Y i X_i, Y_i Xi,Yi 的值在 0 ~ 5000 之间,所以可以建立一个二维数组 A A A,其中, A [ i ] [ j ] A[i][j] A[i][j] 就等于位置 ( i , j ) (i,j) (i,j) 上的所有目标的价值之和。即对于每个目标,令 A [ X i ] [ Y i ] + = W i A[X_i][Y_i] += W_i A[Xi][Yi]+=Wi。
接下来求出  
     
      
       
       
         A 
        
       
      
        A 
       
      
    A 的二维前缀和  
     
      
       
       
         S 
        
       
      
        S 
       
      
    S,即:
  
      
       
        
        
          S 
         
        
          [ 
         
        
          i 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          ] 
         
        
          = 
         
         
         
           ∑ 
          
          
          
            x 
           
          
            = 
           
          
            1 
           
          
         
           i 
          
         
         
         
           ∑ 
          
          
          
            y 
           
          
            = 
           
          
            1 
           
          
         
           j 
          
         
        
          A 
         
        
          [ 
         
        
          x 
         
        
          ] 
         
        
          [ 
         
        
          y 
         
        
          ] 
         
        
       
         S[i][j] = \sum_{x=1}^{i}\sum_{y=1}^j A[x][y] 
        
       
     S[i][j]=x=1∑iy=1∑jA[x][y]
 如下图所示,再观察  
     
      
       
       
         S 
        
       
         [ 
        
       
         i 
        
       
         ] 
        
       
         [ 
        
       
         j 
        
       
         ] 
        
       
         , 
        
       
         S 
        
       
         [ 
        
       
         i 
        
       
         − 
        
       
         1 
        
       
         ] 
        
       
         [ 
        
       
         j 
        
       
         ] 
        
       
         , 
        
       
         S 
        
       
         [ 
        
       
         i 
        
       
         ] 
        
       
         [ 
        
       
         j 
        
       
         − 
        
       
         1 
        
       
         ] 
        
       
         , 
        
       
         S 
        
       
         [ 
        
       
         i 
        
       
         − 
        
       
         1 
        
       
         ] 
        
       
         [ 
        
       
         j 
        
       
         − 
        
       
         1 
        
       
         ] 
        
       
      
        S[i][j],S[i-1][j],S[i][j-1],S[i-1][j-1] 
       
      
    S[i][j],S[i−1][j],S[i][j−1],S[i−1][j−1] 的关系。
 
 容易得到如下的递推式:
  
      
       
        
        
          S 
         
        
          [ 
         
        
          i 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          ] 
         
        
          = 
         
        
          S 
         
        
          [ 
         
        
          i 
         
        
          − 
         
        
          1 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          ] 
         
        
          + 
         
        
          S 
         
        
          [ 
         
        
          i 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          − 
         
        
          1 
         
        
          ] 
         
        
          − 
         
        
          S 
         
        
          [ 
         
        
          i 
         
        
          − 
         
        
          1 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          − 
         
        
          1 
         
        
          ] 
         
        
          + 
         
        
          A 
         
        
          [ 
         
        
          i 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          ] 
         
        
       
         S[i][j] = S[i-1][j] + S[i][j - 1] - S[i-1][j-1] + A[i][j] 
        
       
     S[i][j]=S[i−1][j]+S[i][j−1]−S[i−1][j−1]+A[i][j]
同理,对于任意一个边长为  
     
      
       
       
         R 
        
       
      
        R 
       
      
    R 的正方形,有:
  
      
       
        
         
         
           ∑ 
          
          
          
            x 
           
          
            = 
           
          
            i 
           
          
            − 
           
          
            R 
           
          
            + 
           
          
            1 
           
          
         
           i 
          
         
         
         
           ∑ 
          
          
          
            y 
           
          
            = 
           
          
            j 
           
          
            − 
           
          
            R 
           
          
            + 
           
          
            1 
           
          
         
           j 
          
         
        
          A 
         
        
          [ 
         
        
          x 
         
        
          ] 
         
        
          [ 
         
        
          y 
         
        
          ] 
         
        
          = 
         
        
          S 
         
        
          [ 
         
        
          i 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          ] 
         
        
          − 
         
        
          S 
         
        
          [ 
         
        
          i 
         
        
          − 
         
        
          R 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          ] 
         
        
          − 
         
        
          S 
         
        
          [ 
         
        
          i 
         
        
          , 
         
        
          j 
         
        
          − 
         
        
          R 
         
        
          ] 
         
        
          + 
         
        
          S 
         
        
          [ 
         
        
          i 
         
        
          − 
         
        
          R 
         
        
          ] 
         
        
          [ 
         
        
          j 
         
        
          − 
         
        
          R 
         
        
          ] 
         
        
       
         \sum_{x = i - R + 1}^i \sum_{y = j-R+1}^jA[x][y] = S[i][j] - S[i-R][j] - S[i, j-R] + S[i-R][j- R] 
        
       
     x=i−R+1∑iy=j−R+1∑jA[x][y]=S[i][j]−S[i−R][j]−S[i,j−R]+S[i−R][j−R]

因此,只需要 O ( N 2 ) O(N^2) O(N2) 递推求出二维前缀和 S S S,然后 O ( N 2 ) O(N^2) O(N2) 枚举边长为 R R R 的正方形的右下角坐标 ( i , j ) (i,j) (i,j),即可通过上式 O ( 1 ) O(1) O(1) 计算出该正方形内所有目标的价值之和,更新答案。上面给出的两个式子蕴含的思想其实就是 “容斥原理”。
值得一提的是,上面将 ( X i , Y i ) (X_i, Y_i) (Xi,Yi) 作为一个“格子”,而原题中 ( X i , Y i ) (X_i, Y_i) (Xi,Yi) 是一个点,并且正方形边上的目标不会被摧毁。实际上,不妨认为这个点就处于 “格子” ( X i , Y i ) (X_i,Y_i) (Xi,Yi) 的中心位置,格子的左上角坐标为 ( X i − 0.5 , Y i − 0.5 ) (X_i - 0.5,Y_i-0.5) (Xi−0.5,Yi−0.5),右下角坐标为 ( X i + 0.5 , Y i + 0.5 ) (X_i + 0.5, Y_i + 0.5) (Xi+0.5,Yi+0.5),而正方形的右下角处于 “格线交点” 上,即一个值为 “□.5” 的坐标。这个转化与原问题是等价的。另外,本题内存限制较为严格,可以省略 A A A 数组,读入时直接向 S S S 中累加。
代码
#include <iostream>
using namespace std;
const int N = 5010;
int S[N][N]; //前缀和数组
int main() {
    int N; //目标数 或者说 点数
    int R;
    cin >> N >> R;
    R = min(R, 5001); 
    for (int i = 0, x, y, w; i < N; i++) {
        cin >> x >> y >> w;
        //为防越界,下标从1开始
        S[x + 1][y + 1] += w;
    }
    
    //求二维前缀和
    for (int i = 1; i <= 5001; i++) {
        for (int j = 1; j <= 5001; j++) {
            S[i][j] += S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1]; 
        }
    }
    //枚举边长为R的正方形
    int res = 0;
    for (int i = R; i <= 5001; i++) {
        for (int j = R; j <= 5001; j++) {
            //因为在正方形边上的不能爆破,所以实质上计算的是边长为R-1的正方形
            res = max(res, S[i][j] - S[i - R][j] - S[i][j - R] + S[i - R][j - R]); 
        }
    }
    cout << res << endl;
    return 0;
}



















