数据点 #2 下载下来可过,然而评测机过不了。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e5 + 5;
int n, q, a[N], rt, cnt;
struct Query{int x, p, id, ans;}b[N];
struct FHQ_Treap{int l, r, k, v, siz, sum;}t[N << 1];
int New (int vv)
{
t[++ cnt].v = t[cnt].sum = vv;
t[cnt].k = rand ();
t[cnt].siz = 1;
return cnt;
}
void push_up (int x)
{
t[x].siz = t[t[x].l].siz + t[t[x].r].siz + 1;
t[x].sum = t[x].v + t[t[x].l].sum + t[t[x].r].sum;
}
void split (int pos, int x, int &l, int &r)
{
if (! pos)return l = r = 0, void ();
if (t[pos].v <= x)
{
l = pos;
split (t[l].r, x, t[l].r, r);
}
else
{
r = pos;
split (t[r].l, x, l, t[r].l);
}
push_up (pos);
}
int merge (int l, int r)
{
if (! l || ! r)return l | r;
int pos;
if (t[l].k <= t[r].k)t[pos = l].r = merge (t[l].r, r);
else t[pos = r].l = merge (l, t[r].l);
push_up (pos);
return pos;
}
void Insert (int val)
{
int l, r;
split (rt, val - 1, l, r);
rt = merge (merge (l, New (val)), r);
}
int Search (int x, int p)
{
if (! x || p <= 0)
return 0;
if (t[t[x].r].sum >= p)
return Search (t[x].r, p);
return Search (t[x].l, p - t[t[x].r].sum - t[x].v) + t[t[x].r].siz + 1;
}
signed main ()
{
ios::sync_with_stdio (0);
cin.tie (0);
cout.tie (0);
srand (time (0));
cin >> n >> q;
for (int i = 1; i <= n; ++ i)
cin >> a[i];
for (int i = 1; i <= q; ++ i)
{
cin >> b[i].x >> b[i].p;
b[i].id = i;
}
sort (b + 1, b + q + 1, [](Query a, Query b){return a.x < b.x;});
int j = 1;
for (int i = 1; i <= n; ++ i)
{
Insert (a[i]);
while (i == b[j].x && j <= q)
{
if (t[rt].sum < b[j].p)
b[j].ans = -1;
else
b[j].ans = Search (rt, b[j].p);
++ j;
}
}
sort (b + 1, b + q + 1, [](Query a, Query b){return a.id < b.id;});
for (int i = 1; i <= q; ++ i)
cout << b[i].ans << '\n';
return 0;
}