为什么本地与 OJ 结果不同,玄关
查看原帖
为什么本地与 OJ 结果不同,玄关
617130
Yorg楼主2024/11/4 08:23

rt, 本地已经通过了全部大样例, 但是在 大样例 & Hack 自测 中寄了

#include <bits/stdc++.h>
const int MAXN = 1e5 + 20;

int T;

int n, m, L, V;

struct node
{
    int d, v, a;
    int Left, Right;
} Car[MAXN];

int p[MAXN];

void Calc(int Now)
{
    if (Car[Now].v > V)
    {
        if (Car[Now].a >= 0)
        {
            Car[Now].Left = Car[Now].d, Car[Now].Right = L;
            return;
        }
        else
        {
            Car[Now].Left = Car[Now].d;
            Car[Now].Right = (int)(std::min(double(L), double(Car[Now].d) + (double)((V * V) - (Car[Now].v * Car[Now].v)) / (2 * Car[Now].a)));
            if (((V * V) - (Car[Now].v * Car[Now].v)) % (2 * Car[Now].a) == 0)
            {
                Car[Now].Right--;
            }
            return;
        }
    }
    else
    {
        if (Car[Now].a > 0)
        {
            Car[Now].Left = ((int)(double(Car[Now].d) + (double)((V * V) - (Car[Now].v * Car[Now].v)) / (2 * Car[Now].a)) > L) ? 0 : (int)(double(Car[Now].d) + (double)((V * V) - (Car[Now].v * Car[Now].v)) / (2 * Car[Now].a));
            if (((V * V) - (Car[Now].v * Car[Now].v)) % (2 * Car[Now].a) == 0 && Car[Now].Left != 0)
            {
                Car[Now].Left++;
            }
            Car[Now].Right = (Car[Now].Left == 0) ? 0 : L;
            return;
        }
        else
        {
            Car[Now].Left = 0, Car[Now].Right = 0;
            return;
        }
    }
}

bool CanBeDetected[MAXN];
class Detect
{
private:
    /*0 符合要求; 1 偏左; 2 偏右*/
    int check(int x, int Now)
    {
        if (p[x] >= Car[Now].Left && p[x] <= Car[Now].Right)
        {
            return 0;
        }
        else if (p[x] < Car[Now].Left)
        {
            return 1;
        }
        else
        {
            return 2;
        }
    }

public:
    bool Bin_Search(int Now)
    {
        int Left = 1, Right = m;
        CanBeDetected[Now] = false;
        while (Left <= Right)
        {
            int Mid = (Left + Right) >> 1;

            int Type = check(Mid, Now);

            if (Type == 0)
            {
                CanBeDetected[Now] = true;
                return CanBeDetected[Now];
            }
            else
            {
                if (Type == 1)
                {
                    Left = Mid + 1;
                }
                else
                {
                    Right = Mid - 1;
                }
            }
        }
    }

    void solve()
    {
        for (int i = 1; i <= n; i++)
        {
            Bin_Search(i);
        }
    }
} detect;

int MustUse = 0;

class Solution
{
private:
    bool check(int Pos, int x)
    {
        if (p[x] >= Pos)
            return true;
        else
            return false;
    }

    int Bin_Search(int Pos)
    {
        int Left = 1, Right = m;
        int Ans = 0;

        while (Left <= Right)
        {
            int Mid = (Left + Right) >> 1;

            if (check(Pos, Mid))
            {
                Ans = Mid;
                Right = Mid - 1;
            }
            else
            {
                Left = Mid + 1;
            }
        }

        return Ans;
    }

    struct Range
    {
        int Left, Right;

        friend bool operator<(Range a, Range b)
        {
            return a.Left < b.Left;
        }
    } Ran[MAXN];
    int cnt;

public:
    void solve()
    {
        cnt = 0, MustUse = 0;
        for (int i = 1; i <= n; i++)
        {
            if (CanBeDetected[i])
                Ran[++cnt].Left = Car[i].Left, Ran[cnt].Right = Car[i].Right;
        }

        std::sort(Ran + 1, Ran + cnt + 1);

        /*倒序扫描*/
        int Min_P = -1;
        for (int i = cnt; i >= 1; i--)
        {
            if (Min_P == -1 || (p[Min_P] < Ran[i].Left || p[Min_P] > Ran[i].Right))
            {
                MustUse++;
                Min_P = Bin_Search(Ran[i].Left);
            }
        }

        printf("%d %d\n", cnt, m - MustUse);
    }
} Sol;

int main()
{
    // freopen("detect5.in", "r", stdin);
    // freopen("detect.out", "w", stdout);

    scanf("%d", &T);
    while (T--)
    {
        /*计算区间*/
        scanf("%d %d %d %d", &n, &m, &L, &V);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d %d %d", &Car[i].d, &Car[i].v, &Car[i].a);
            Calc(i);
        }

        for (int i = 1; i <= m; i++)
        {
            scanf("%d", &p[i]);
        }

        /*计算有多少个区间会被检测到 O(NlogM)*/
        detect.solve();

        /*贪心处理*/
        Sol.solve();
    }

    return 0;
}

/*
1
5 5 15 3
0 3 0
12 4 0
1 1 4
5 5 -2
6 4 -4
2 5 8 9 15

3 3
*/
2024/11/4 08:23
加载中...