题目链接:https://vjudge.net/problem/Gym-102307E
题意:平面上n个点,给定区域的w和d范围,求区域最大的点数
题解:其实和在平面上给定长和宽 是一样的道理,这个只需要对角度排序,然后对于每个点保存[x - d, d] 然后取最大值即可,注意一点是因为他是一圈,所以n个点再加n个放到后面继续求即可,但这个比较坑的是,w是小数,直接比较在case12就错了,因为这个只有小数点两位所以可以先转化为整数,或者加上eps判断
转化为整数:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const double eps = 1e-8;
struct node {
int l, r;
int maxx, laz;
}tree[N << 2];
struct node1 {
int r, w;
}a[N << 1];
int n, d, du;
bool cmp(const node1 &x, const node1 &y) {
return x.w < y.w;
}
void build(int l, int r, int cur) {
tree[cur].l = l;
tree[cur].r = r;
tree[cur].laz = 0;
tree[cur].maxx = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(l, mid, cur << 1);
build(mid + 1, r, cur << 1 | 1);
}
void pushup(int cur) {
tree[cur].maxx = max(tree[cur << 1].maxx, tree[cur << 1 | 1].maxx);
}
void pushdown(int cur) {
if(tree[cur].laz) {
tree[cur << 1].laz += tree[cur].laz;
tree[cur << 1 | 1].laz += tree[cur].laz;
tree[cur << 1].maxx += tree[cur].laz;
tree[cur << 1 | 1].maxx += tree[cur].laz;
tree[cur].laz = 0;
}
}
void update(int pl, int pr, int cur, int val) {
if(pl <= tree[cur].l && tree[cur].r <= pr) {
tree[cur].laz += val;
tree[cur].maxx += val;
return;
}
pushdown(cur);
if(pl <= tree[cur << 1].r) update(pl, pr, cur << 1, val);
if(pr >= tree[cur << 1 | 1].l) update(pl, pr, cur << 1 | 1, val);
pushup(cur);
}
int main() {
double x;
scanf("%d %d %lf", &n, &d, &x);
du = (int)(x * 100 + eps);
for(int i = 1; i <= n; i++) {
scanf("%d %lf", &a[i].r, &x);
a[i].w = (int)(x * 100 + eps);
}
sort(a + 1, a + 1 + n, cmp);
build(1, 100000, 1);
for(int i = 1; i <= n; i++) a[i + n] = a[i], a[i + n].w += 36000;
n = n * 2;
int ans = 0;
for(int i = 0, j = 1, k; i < n;) {
k = i + 1;
while(k <= n && a[k].w == a[i + 1].w ) {
update(max(1, a[k].r - d), a[k].r, 1, 1);
k++;
}
i = k - 1;
while(a[j].w + du < a[i].w) {
update(max(1, a[j].r - d), a[j].r, 1, -1);
j++;
}
ans = max(ans, tree[1].maxx);
}
printf("%d\n", ans);
return 0;
}
小数用eps判断:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const double eps = 1e-8;
struct node {
int l, r;
int maxx, laz;
}tree[N << 2];
struct node1 {
int r, w;
}a[N << 1];
int n, d, du;
bool cmp(const node1 &x, const node1 &y) {
return x.w < y.w;
}
void build(int l, int r, int cur) {
tree[cur].l = l;
tree[cur].r = r;
tree[cur].laz = 0;
tree[cur].maxx = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(l, mid, cur << 1);
build(mid + 1, r, cur << 1 | 1);
}
void pushup(int cur) {
tree[cur].maxx = max(tree[cur << 1].maxx, tree[cur << 1 | 1].maxx);
}
void pushdown(int cur) {
if(tree[cur].laz) {
tree[cur << 1].laz += tree[cur].laz;
tree[cur << 1 | 1].laz += tree[cur].laz;
tree[cur << 1].maxx += tree[cur].laz;
tree[cur << 1 | 1].maxx += tree[cur].laz;
tree[cur].laz = 0;
}
}
void update(int pl, int pr, int cur, int val) {
if(pl <= tree[cur].l && tree[cur].r <= pr) {
tree[cur].laz += val;
tree[cur].maxx += val;
return;
}
pushdown(cur);
if(pl <= tree[cur << 1].r) update(pl, pr, cur << 1, val);
if(pr >= tree[cur << 1 | 1].l) update(pl, pr, cur << 1 | 1, val);
pushup(cur);
}
int main() {
double x;
scanf("%d %d %lf", &n, &d, &x);
du = (int)(x * 100 + eps);
for(int i = 1; i <= n; i++) {
scanf("%d %lf", &a[i].r, &x);
a[i].w = (int)(x * 100 + eps);
}
sort(a + 1, a + 1 + n, cmp);
build(1, 100000, 1);
for(int i = 1; i <= n; i++) a[i + n] = a[i], a[i + n].w += 36000;
n = n * 2;
int ans = 0;
for(int i = 0, j = 1, k; i < n;) {
k = i + 1;
while(k <= n && a[k].w == a[i + 1].w ) {
update(max(1, a[k].r - d), a[k].r, 1, 1);
k++;
}
i = k - 1;
while(a[j].w + du < a[i].w) {
update(max(1, a[j].r - d), a[j].r, 1, -1);
j++;
}
ans = max(ans, tree[1].maxx);
}
printf("%d\n", ans);
return 0;
}