TLE on test 27 求调, 玄关
  • 板块CF1997E Level Up
  • 楼主Yorg
  • 当前回复6
  • 已保存回复6
  • 发布时间2024/10/22 10:31
  • 上次更新2024/10/22 14:45:54
查看原帖
TLE on test 27 求调, 玄关
617130
Yorg楼主2024/10/22 10:31
#include <bits/stdc++.h>

const int MAXN = 2e5 + 20;
const int MAXSQRTN = 500;

int n, q;
int Mons_Level[MAXN];
int Sum[MAXN][MAXSQRTN]; // Sum_{i, j} 表示前 i 个数里面 <= j 的数的多少

inline int read()
{
    int x = 0, w = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') { 
        if (ch == '-') w = -1;
        ch = getchar(); 
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0'); 
        ch = getchar();
    }
    return x * w;
}

void Pre_Calc()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= 450; j++)
        {
            Sum[i][j] += Sum[i - 1][j];
            Sum[i][j] += (int)(Mons_Level[i] <= j);
        }
    }
}

std::string Brute(int Pos, int k)
{
    int Now_Level = 1;
    int Fight_Time = 0;
    for (int i = 1; i <= Pos; i++)
    {
        if (Fight_Time == k)
        {
            Now_Level++;
            Fight_Time = 0;
        }

        if (i == Pos)
        {
            if (Now_Level > Mons_Level[i])
            {
                return "NO";
            }
            else
            {
                return "YES";
            }
        }

        if (Now_Level <= Mons_Level[i])
        {
            Fight_Time++;
        }
    }
    return "ERROR";
}

struct node
{
    int Pos;
    int Num;
};

std::vector<node> Que[MAXN];

std::string Ans[MAXN];

bool cmp(node a, node b);

bool check(int k, int Left, int Right, int Now_Level)
{
    return (Right - Left + 1) - (Sum[Right][Now_Level - 1] - Sum[Left - 1][Now_Level - 1]) >= k;
}

/*二分查找符合要求的 R*/
int Bin_Search(int Now_Left, int &Now_Right, int Now_Level, int k)
{
    int Left = Now_Left, Right = n;
    Now_Right = n;
    while (Left < Right)
    {
        int Mid = Left + ((Right - Left) >> 1);
        if (check(k, Now_Left, Mid, Now_Level))
        {
            Now_Right = Mid;
            Right = Mid;
        }
        else
        {
            Left = Mid + 1;
        }
    }
    return Now_Right;
}

bool cmp(node a, node b) { return ((a.Pos == b.Pos) ? (a.Num < b.Num) : (a.Pos < b.Pos)); }

int main()
{

    n = read(), q = read();
    for (int i = 1; i <= n; i++)
    {
        Mons_Level[i] = read();
    }

    /*预处理*/
    Pre_Calc();

    for (int i = 1; i <= q; i++)
    {
        int Pos, k;
        Pos = read(), k = read();
        Que[k].push_back((node){Pos, i});
    }

    for (int k = 1; k <= n; k++)
    {
        if (Que[k].empty())
            continue;

        int Have_Done = 0;

        /*暴力处理*/
        if (k <= 448)
        {
            for (int i = 0; i < Que[k].size(); i++)
            {
                Ans[Que[k][i].Num] = Brute(Que[k][i].Pos, k);
            }
        }
        else
        {
            /*这里需要对查询排序*/
            sort(Que[k].begin(), Que[k].end(), cmp);

            int Now_Left = 1, Now_Right = -1, Now_Level = 1;
            Have_Done = 0;
            /*分段处理当前 k*/
            while (Now_Left <= n)
            {
                Now_Right = Bin_Search(Now_Left, Now_Right, Now_Level, k);

                while (Have_Done < Que[k].size() && Now_Left <= Que[k][Have_Done].Pos && Que[k][Have_Done].Pos <= Now_Right)
                {
                    if (Now_Level <= Mons_Level[Que[k][Have_Done].Pos])
                    {
                        Ans[Que[k][Have_Done].Num] = "YES";
                    }
                    else
                    {
                        Ans[Que[k][Have_Done].Num] = "NO";
                    }
                    Have_Done++;
                }

                Now_Left = Now_Right + 1;
                Now_Level++;
            }
        }
    }

    for (int i = 1; i <= q; i++)
    {
        std::cout << Ans[i] << '\n';
    }

    return 0;
}

思路类似于第三篇 tj

2024/10/22 10:31
加载中...