#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