码迷,mamicode.com
首页 > 其他好文 > 详细

CF1409E 两个平台

时间:2021-02-06 11:47:59      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:碰撞   c++   stream   ORC   n+1   情况   停止   name   image   

1 CF1409E 两个平台

2 题目描述

平面上有 \(n\) 个点。第 \(i\) 点的坐标是 \((x_i, y_i)\)。你有两个长度为 \(k\) 的水平平台。每个平台可以放置在平面上的任何地方,但它应该水平放置(在同一个 \(y\) 坐标上),平台的边框都为整数。如果平台的左边框是 \((x,y)\),那么右边框是 \((x+k,y)\),边界之间的所有点(包括边框)都属于平台。

请注意,平台可以共享公共点(重叠),不需要将两个平台放置在同一个 \(y\) 坐标上。

当你把两个平台放在一个平面上时,所有的点都开始沿着 \(y\) 坐标下降。如果某个点在某个时刻与某个平台发生碰撞,则该点停止并且被保存。从未与任何平台碰撞的点都会丢失。

任务是找出可以保存的最大的点数的两个平台放置的最优化方案。

必须完成 \(t\) 个独立的测试用例。

3 题解

我们观察发现:\(y\) 坐标没有用处且最优情况两个板子肯定都在某个点的横坐标上,同时两块板子还不重叠。我们由此可以先计算出每个数往后延伸 \(k\) 可以够到的最远距离,然后问题就变成了这样:

给出一个数组 \(a\),求出\(max_{i = 1}^{n} (a_i + max_{j = a_i+i}^{n} a_j)\)

我们发现,\(max_{j = a_i+i}^{n} a_j\) 我们可以用线段树维护,时间复杂度为 \(O(n)\)

4 代码(空格警告):

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 2e5+10;
int T;
int n, k, x, Ans;
int a[N], b[N];
struct node
{
    int l, r, maxn;
}t[N*4];
void build(int p, int l, int r)
{
    t[p].l = l;
    t[p].r = r;
    if (l == r)
    {
        t[p].maxn = b[l];
        return ;
    }
    int mid = (l+r)/2;
    build(p*2, l, mid);
    build(p*2+1, mid+1, r);
    t[p].maxn = max(t[p*2].maxn, t[p*2+1].maxn);
}
int query(int p, int l, int r)
{
    if (l > r) return 0;
    if (t[p].l >= l && t[p].r <= r) return t[p].maxn;
    int mid = (t[p].l + t[p].r) / 2;
    int ans = -0x3f3f3f3f;
    if (l <= mid) ans = max(ans, query(p*2, l, r));
    if (r > mid) ans = max(ans, query(p*2+1, l, r));
    return ans;
}
int main()
{
    scanf("%d", &T);
    while (T--)
    {
        Ans = 0;
        scanf("%d %d", &n, &k);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        sort(a+1, a+n+1);
        for (int i = 1; i <= n; i++) scanf("%d", &x);
        x = 1;
        for (int i = 1; i <= n; i++)
        {
            while (a[x] <= a[i] + k && x != n+1) x++;
            b[i] = x - i;
        }
        build(1, 1, n);
        for (int i = 1; i <= n; i++)
        {
            Ans = max(Ans, b[i] + query(1, b[i]+i, n));
        }
        cout << Ans << ‘\n‘;
    }
    return 0;
}

欢迎关注我的公众号:智子笔记

技术图片

CF1409E 两个平台

标签:碰撞   c++   stream   ORC   n+1   情况   停止   name   image   

原文地址:https://www.cnblogs.com/david24/p/14378053.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!