牛客網Popping Balloons【線分樹】
标题:座標軸にn個の点(n<=1 e 5)を与え、点の横長座標は[0,1 e 5]で、3行を選択することができ、各行間隔はdで、3列の同じ間隔dを選択し、点は1回しか選択できず、最大何点を選択できるかを聞く.d<=1e5
考え方:num[j]+num[j+d]+num[j+2 d]の値を1本のセグメントツリーを作成し、選択したポイントを削除し、セグメントツリーで最大値を検索すればいいと考えています.ポイントを削除するときは、自分のx,x-d,x-2 dの位置にのみ影響します.クエリーを削除した後、追加し直します.
考え方:num[j]+num[j+d]+num[j+2 d]の値を1本のセグメントツリーを作成し、選択したポイントを削除し、セグメントツリーで最大値を検索すればいいと考えています.ポイントを削除するときは、自分のx,x-d,x-2 dの位置にのみ影響します.クエリーを削除した後、追加し直します.
#include
using namespace std;
typedef long long ll;
#define ls rt << 1
#define rs rt << 1|1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
const int N = 100005;
const int maxn = 2e5 + 10;
const ll inf = 0x3f3f3f3f3f3f3f3f;
vector v[maxn];
int num[maxn]; //
ll tree[maxn << 2];
int n, d;
void push_up(int rt)
{
tree[rt] = max(tree[ls], tree[rs]);
}
void build(int l, int r, int rt)
{
if(l == r)
{
for(int i = 0; i < 3; ++i)
if(l + i * d <= N)
tree[rt] += num[l + i * d];
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
push_up(rt);
}
void update(int pos, int val, int l, int r, int rt)
{
if(l < 0 || r > N || pos < 0 || pos > N)
return;
if(l == r)
{
tree[rt] += val;
return;
}
int mid = (l + r) >> 1;
if(pos <= mid)
update(pos, val, lson);
else
update(pos, val, rson);
push_up(rt);
}
ll query(int ql, int qr, int l, int r, int rt)
{
if(ql <= l && r <= qr)
return tree[rt];
int mid = (l + r) >> 1;
ll ret = -inf;
if(ql <= mid)
ret = max(ret, query(ql, qr, lson));
if(qr > mid)
ret = max(ret, query(ql, qr, rson));
return ret;
}
int main()
{
scanf("%d%d", &n, &d);
for(int i = 1; i <= n; ++i)
{
int x, y;
scanf("%d%d", &x, &y);
v[y].push_back(x);
num[x]++;
}
build(0, N, 1);
ll ans = 1;
for(int i = 0; i <= N; ++i) //
{
ll tmp = 0;
for(int j = 0; j < 3; ++j)
{
if((ll)(i + j * d) <= N)
{
tmp += v[i + j * d].size();
for(auto x : v[i + j * d])
{
update(x, -1, 0, N, 1);
update(x - d, -1, 0, N, 1);
update(x - 2 * d, -1, 0, N, 1);
}
}
}
tmp += query(0, N, 0, N, 1);
ans = max(ans, tmp);
for(int j = 0; j < 3; ++j)
{
if((ll)(i + j * d) <= N)
{
for(auto x : v[i + j * d])
{
update(x, 1, 0, N, 1);
update(x - d, 1, 0, N, 1);
update(x - 2 * d, 1, 0, N, 1);
}
}
}
}
printf("%lld
", ans);
return 0;
}