专栏文章
题解:P13787 地毯 加强版
P13787题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mio7lthg
- 此快照首次捕获于
- 2025/12/02 14:40 3 个月前
- 此快照最后确认于
- 2025/12/02 14:40 3 个月前
题目描述
在 的地图上,有 条地毯,求每个格子上的地毯覆盖数。
思路分析
方法一(TLE)
最简单的方法即为暴力。使用二维数组 记录每个格子的地毯覆盖数,每次遍历地毯所覆盖的每一个格子。
CPP#include <bits/stdc++.h>
#define N 5005
#define int long long
using namespace std;
int n,m;
int a[N][N];
int sum;
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i=1;i<=m;++i){
int x1,y1,x2,y2; cin >> x1 >> y1 >> x2 >> y2;
for (int x=x1;x<=x2;++x){
for (int y=y1;y<=y2;++y){
a[x][y]++;
}
}
}
for (int i=1;i<=n;++i){
for (int j=1;j<=n;++j){
sum += (i + j) ^ a[i][j];
}
}
cout << sum;
return 0;
}
这样实现的时间复杂度为 ,观察数据范围,很明显会超时。
方法二(50 Pts)
- 对于所有 ,预处理出 。(由于本题初始数组元素都为 ,所以无需进行此操作)
- 读入 与 ,修改此区间的两个端点的值,使 加 , 减 。
- 每行从左往右扫描一遍,跑一遍一维前缀和,即使 ,就可以得到每个格子的地毯覆盖数。
代码如下:
CPP#include <bits/stdc++.h>
#define N 5005
#define int long long
using namespace std;
int n,m;
int a[N][N];
int sum;
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i=1;i<=m;++i){
int x1,y1,x2,y2; cin >> x1 >> y1 >> x2 >> y2;
for (int j=x1;j<=x2;++j) a[j][y1]++,a[j][y2+1]--;
}
for (int i=1;i<=n;++i){
for (int j=1;j<=n;++j){
a[i][j] += a[i][j-1];
sum += (i + j) ^ a[i][j];
}
}
cout << sum;
return 0;
}
但是,这样实现的时间复杂度为 ,观察数据范围,很明显依旧无法被接受。
方法三(100 Pts)
由于此题 ,所以对于读入地毯还需再压掉一维,即将读入地毯的时间复杂度压为 ,于是我们需要使用二维差分。
假设一个二维数组 ,二维差分的方法为:
- 对于所有 与 ,预处理出 。(由于本题初始数组元素都为 ,所以无需进行此操作)
- 读入 、、 与 ,修改此矩形的四个端点的值,使 加 , 减 , 减 , 加 。
- 从上到下、从左往右扫描一遍,跑一遍二维前缀和,即使 ,就可以得到每个格子的地毯覆盖数。
代码如下:
CPP#include <bits/stdc++.h>
#define N 5005
#define int long long
using namespace std;
int n,m;
int a[N][N];
int sum;
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i=1;i<=m;++i){
int x1,y1,x2,y2; cin >> x1 >> y1 >> x2 >> y2;
a[x1][y1]++;
a[x1][y2+1]--;
a[x2+1][y1]--;
a[x2+1][y2+1]++;
}
for (int i=1;i<=n;++i){
for (int j=1;j<=n;++j){
a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1];
sum += (i + j) ^ a[i][j];
}
}
cout << sum;
return 0;
}
此代码的时间复杂度为 ,可以通过此题。
注意
不开 long long 见祖宗
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...