p3397题解
题目链接:https://www.luogu.com.cn/problem/P3397
这是一道二维前缀和的题目
题目简述:给定一个n*n的格子,有m次输入,每次输入会给你地毯的左上角和右下角,要求输出每个格子上的地毯数量
这道题数据比较水,暴力好像也能过
暴力思路:对每一次输入fx,fy(左上角) ex,ey(右下角)
点击查看代码
for(int i=fx;i<=ex;i++)
{
for(int j=fy;j<=ey;j++)
{
mp[i][j]++;
}
}
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int diff[1005][1005];
signed main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int fx,fy,ex,ey;
cin>>fx>>fy>>ex>>ey;
/*
* 二维差分操作:
* 对矩形区域 (fx,fy) → (ex,ey) 整体 +1
*/
diff[fx][fy]++;// 矩形左上角 +1
diff[fx][ey+1]--; // 矩形右上角外 -1
diff[ex+1][fy]--; // 矩形左下角外 -1
diff[ex+1][ey+1]++;// 矩形右下角外 +1(抵消两次 -1)
}
// 还原二维前缀和
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
/*
* 容斥原理:
* 当前格子 = 上 + 左 - 左上 + 自身
*
* diff[i][j] 此时已经是“增量”
* 通过累加变成真实覆盖次数
*/
diff[i][j]+=diff[i-1][j]+diff[i][j-1]-diff[i-1][j-1];
cout<<diff[i][j];
if(j!=n) cout<<' ';
}
cout<<endl;
}
return 0;
}


浙公网安备 33010602011771号