set+map+倍增,不能吐槽更多。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
template<class Num>void read(Num &x)
{
char c; int flag = 1;
while((c = getchar()) < '0' || c > '9')
if(c == '-') flag *= -1;
x = c - '0';
while((c = getchar()) >= '0' && c <= '9')
x = (x<<3) + (x<<1) + (c-'0');
x *= flag;
return;
}
template<class Num>void write(Num x)
{
if(!x) {putchar('0');return;}
if(x < 0) putchar('-'), x = -x;
static char s[20];int sl = 0;
while(x) s[sl++] = x%10 + '0',x /= 10;
while(sl) putchar(s[--sl]);
}
const int maxn = 1e5 + 50, logN = 18;
int n, m, H[maxn], S, x, l;
std::set<int> set;
std::map<int,int> map;
int step[maxn][logN];
long long walk[maxn][logN][2];
int next[maxn][2], len[maxn][2];
void init()
{
std::set<int>::iterator pre, sur;
static std::pair<int,int> t[5];
read(n);
for(int i = 1; i <= n; i++)
read(H[i]), map[H[i]] = i;
for(int i = n; i >= 1; i--)
{
l = 0, set.insert(H[i]);
pre = sur = set.lower_bound(H[i]);
if(pre != set.begin())
{
t[++l].second = *(--pre);
if(pre != set.begin())
t[++l].second = *(--pre);
}
if(++sur != set.end())
{
t[++l].second = *sur;
if(++sur != set.end())
t[++l].second = *sur;
}
for(int j = 1; j <= l; j++)
t[j].first = abs(H[i] - t[j].second);
std::sort(t + 1, t + l + 1);
if(l >= 1)
{
next[i][1] = map[t[1].second];
len[i][1] = t[1].first;
}
if(l >= 2)
{
next[i][0] = map[t[2].second];
len[i][0] = t[2].first;
}
step[i][0] = next[next[i][0]][1];
walk[i][0][0] = len[i][0];
walk[i][0][1] = len[next[i][0]][1];
for(int j = 1; j < logN; j++)
{
step[i][j] = step[step[i][j - 1]][j - 1];
walk[i][j][0] = walk[i][j - 1][0] + walk[step[i][j - 1]][j - 1][0];
walk[i][j][1] = walk[i][j - 1][1] + walk[step[i][j - 1]][j - 1][1];
}
}
}
void query(int s,int lim,long long &a,long long &b)
{
for(int i = logN - 1; i >= 0; i--)
{
if(walk[s][i][0] + walk[s][i][1] <= lim)
{
lim -= walk[s][i][0] + walk[s][i][1];
a += walk[s][i][0], b += walk[s][i][1];
s = step[s][i];
}
}
if(len[s][0] <= lim) a += len[s][0];
}
void solve()
{
long long distA = 1, distB = 0;
long long A, B;
read(x), S = 0;
for(int i = 1; i <= n; i++)
{
query(i, x, A = 0, B = 0);
if(A * distB < B * distA)
{
distA = A, distB = B;
S = i;
}
}
write(S), puts("");
read(m);
for(int i = 1; i <= m; i++)
{
read(S), read(x);
query(S, x, A = 0, B = 0);
write(A), putchar(' ');
write(B), puts("");
}
}
int main()
{
init();
solve();
return 0;
}