题目链接:
D-异或炸弹(easy)_牛客小白月赛95 (nowcoder.com)
题目:
题目分析:
一看 还以为是二维差分的题呢 到后来才发现是一维差分问题
这里的距离是 曼哈顿距离 dis = abs(x - xi) + abs(y - yi) 暴力的做法 就是枚举 n * n 个点 然后看看这n * n 个点到m次询问的点的距离是否小于等于r 但是时间复杂度为O(n *n * m )太高了 一定会TLE的其实发现 在每一行里面 满足的都是一段连续的 那么差分就排上用场了 a[l] ++, a[r + 1] --
枚举每一行 也就是定一个x 那么y的范围也就出来了 因为 abs(x - xi) + abs(y - yi) <= r 那么 y 的范围就是 yi - 剩余的(r - x到xi的距离) 到 yi + 剩余的(r - x到xi的距离) 这个y 就可以用差分去解决 注意边界问题 以及绝对值
需要注意的是 下面的代码里面的一个边界 a[i][min(n + 1, y + dis + 1)] -- ; 注意是 n + 1 要是写成 n 的话 表示的意思 就是 y为n的这个点 就永远取不到了 细节问题
代码:
#include<bits/stdc++.h>
#define y1 Y1
#define fi first
#define endl "\n"
#define se second
#define PI acos(-1)
#define int long long
#define pb(x) push_back(x)
#define PII pair<int, int>
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int N = 3000 + 10;
const int mod = 1e9 + 7;
int a[N][N];
int n, m, t, ret;
string s;
signed main() {
IOS;
cin >> n >> m;
while(m -- ) {
int x, y, r;
cin >> x >> y >> r;
// 这里用的还是一维的差分的知识
for(int i = max(1ll, x - r); i <= min(n, r + x); i ++ ) {
int dis = r - abs(x - i); // 只要y在这个范围内就可以
a[i][max(1ll, y - dis)] ++ ;
a[i][min(n + 1, y + dis + 1)] -- ;
}
}
for(int i = 1; i <= n; i ++ ) {
t = 0;
for(int j = 1; j <= n; j ++ ) {
t += a[i][j];
if(t % 2 == 1)ret ++ ;
}
}
cout << ret << endl;
return 0;
}