洛谷:P3397:地毯


洛谷:P3397:地毯

Table of Contents

题目

P3397:地毯

分析

这题与P2367:语文成绩很相似,也要用到差分和前缀和,但这次是在一个矩阵中进行。

其核心公式是:

  1. 差分公式:\(diff[i][j]=a[x][y]-a[x-1][y]-a[x][y-1]+a[x-1][y-1]\)
  2. 前缀和公式:\(a[i][j]=\sum_{i=1}^{x}\sum_{j=1}^{y}diff[i][j]\)

参照一维的情形,要修改\([x, y]\)之间的值的时候,我们是将diff[x]+=z, diff[y+1]-=z。而求部分和的时候,是diff[y]+=diff[x-1]。(参见P2367:语文成绩中的代码。)

扩展到二维时,从\([x-1][y-1]\)扩展到\([x][y]\)时,需要有两个方向的扩展:\(x-1\to x, y-1\to y\),但这么一来\([x, y]\)计算了两次,所以最终要调整一次。

因此,差分公式需要调整:

  • diff[x1, y1]++; //起始点增加
  • diff[x2+1][y1]-- //纵向终点调整
  • diff[x1][y2+1]-- //横向终点调整
  • diff[x2+1][y2+1]++ //最终调整

所以,最终的前缀和公式就变成:a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1]

答案

Solution

思考

特别注意:代码中向量的大小都调整到了size+2,设定为size+1会出现越界,因为我们在代码中要操作到size+1的位置:

    for(int i=1;i<=carpets_count;i++)
    {
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;

        ranges[x1][y1]++;
        ranges[x1][y2+1]--;
        ranges[x2+1][y1]--;
        ranges[x2+1][y2+1]++;
    }

Previous Next